cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Strange query error

Neo4j community server 4.4.5 on Ubuntu 20.04 - browser

I have the following query. The idea is to create all relationships between nodes and to signal all the missing relationship making them pointing to a fake node.

The query returns the following error

WITH is required between MERGE and MATCH (line 43, column 2 (offset: 716))
"	MATCH (organisation:Organisation { id: row.organisation_id})"
  ^

but the WITH statement is already there (I evidenced it between backticks).

Any idea on how to solve the problem, or in alternative, any idea how to evidence the missing matching?


MATCH (n:AssetContract)-[r]-() detach delete n,r;
MATCH (n:AssetContract) delete n;

LOAD CSV WITH HEADERS 
FROM 'file:///asset_contracts.csv' 
AS row 
FIELDTERMINATOR ';'
WITH row

CREATE (asset_contract:AssetContract)
		SET asset_contract=row,
			asset_contract.uuid=apoc.create.uuid()

WITH asset_contract,row

MATCH (asset:Asset { id: row.asset_id})

WITH asset,asset_contract,row

CALL {

	WITH asset,asset_contract,row
	
	WITH asset,asset_contract,row
		WHERE asset IS NULL

	MERGE (noAsset:NoAsset)

	MERGE (asset_contract)-[:MISSING_ASSET]->(noAsset)

	return 1 as ret
}

CALL {

	WITH asset,asset_contract,row
	
	WITH asset,asset_contract,row
		WHERE asset IS NOT NULL

	MERGE (asset)-[:HAS_CONTRACT]->(asset_contract)
		//SET asset_contract.asset_id = NULL

	`WITH asset,asset_contract,row`

	MATCH (organisation:Organisation { id: row.organisation_id})

	WITH asset, row, organisation

		CALL {
			WITH asset, row, organisation

			WITH asset, row, organisation
				WHERE organisation IS NULL

			MERGE (noOrganisation:NoOrganisation)

			MERGE (asset)-[:MISSING_ORGANIZATION]->(noOrganisation)

			return 2 as ret2
		}

	WITH asset, row, organisation

		CALL {
			WITH asset, row, organisation

			WITH asset, row, organisation
				WHERE organisation IS NOT NULL

			MERGE (asset)-[:BELONGS_TO]->(organisation)
				
			return 3 as ret3	
		}

}

	RETURN COUNT(asset_contract)
1 ACCEPTED SOLUTION

Sure thing.

Note, I made a small edit to the code above, after I realized the 'call' clause is not needed to wrap the 'optional match' on the 'asset' node.

At this point, it seems this script works. Here are some tests results:

  1. Missing 'asset' / missing 'organisation'

  2. Missing 'asset' / with 'organisation'

  3. Found 'asset' / Missing 'organization'

  4. Found 'asset' / found 'organisation'

View solution in original post

9 REPLIES 9

Is Organization missing in with clause?(where it is pointing as error)

Is Organization missing in with clause?(where it is pointing as error)

No, organisation is not missing, because it is matched in the next line and doesn't exists before

I deleted the above post because I realized it did not provide the same functionality. The asset_contract was not returned when the asset was null.

The script seems to have too many conditional execution paths, which cypher doesn't seem designed to handle. Can you simplify your tasks by creating one script that imports the file and creates the nodes/relationship when the asset is not null and one that does what is required when the asset node is null. It would be easy to split this script into those two, then run one after the other.

I delete the previous post because I noticed it was not working when I started testing it. This version seems to work. The key was the use of OPTIONAL MATCH, so the query would not terminate. I tested the scenarios with and without the asset and organisation nodes.

LOAD CSV WITH HEADERS FROM 'file:///asset_contract.txt' AS row FIELDTERMINATOR ';'

CREATE (asset_contract:AssetContract)
		SET asset_contract = row,
			asset_contract.uuid=apoc.create.uuid()

WITH asset_contract, row	

OPTIONAL MATCH (asset:Asset {id: row.asset_id})

CALL {
	WITH asset, asset_contract
	WITH asset, asset_contract
	WHERE asset IS NULL
	MERGE (noAsset:NoAsset)
	MERGE (asset_contract)-[:MISSING_ASSET]->(noAsset)
}

CALL {
	WITH asset, asset_contract, row
	WITH asset, asset_contract, row
	WHERE asset IS NOT NULL
	
	MERGE (asset)-[:HAS_CONTRACT]->(asset_contract)
		// SET asset_contract.asset_id = NULL
}

OPTIONAL MATCH (organisation:Organisation { id: row.organisation_id})

CALL {
	WITH organisation, asset
	WITH organisation, asset
	WHERE asset IS NOT NULL AND organisation IS NULL
	MERGE (noOrganisation:NoOrganisation)
	MERGE (asset)-[:MISSING_ORGANIZATION]->(noOrganisation)
}
		
CALL {
	WITH organisation, asset
	WITH organisation, asset
	WHERE asset IS NOT NULL AND organisation IS NOT NULL
    MERGE (asset)-[:BELONGS_TO]->(organisation)	
}

RETURN asset_contract, asset, organisation

I'll check it tomorrow morning. But the suggestion to split the process in two parts, one managing the NULL branch and the other the NOT NULL looks reasonable!

Sure thing.

Note, I made a small edit to the code above, after I realized the 'call' clause is not needed to wrap the 'optional match' on the 'asset' node.

At this point, it seems this script works. Here are some tests results:

  1. Missing 'asset' / missing 'organisation'

  2. Missing 'asset' / with 'organisation'

  3. Found 'asset' / Missing 'organization'

  4. Found 'asset' / found 'organisation'

Not clear which call clause is not required. Can you repost the entire query?

Sorry, I updated the last query posted. It is the full query.