Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
04-08-2022 08:21 AM
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)
Solved! Go to Solution.
04-10-2022 07:02 AM
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:
Missing 'asset' / missing 'organisation'
Missing 'asset' / with 'organisation'
Found 'asset' / Missing 'organization'
Found 'asset' / found 'organisation'
04-09-2022 07:07 AM
Is Organization missing in with clause?(where it is pointing as error)
04-09-2022 07:07 AM
Is Organization missing in with clause?(where it is pointing as error)
04-09-2022 09:09 AM
No, organisation is not missing, because it is matched in the next line and doesn't exists before
04-09-2022 01:35 PM
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.
04-09-2022 11:29 PM
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
04-10-2022 03:46 AM
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!
04-10-2022 07:02 AM
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:
Missing 'asset' / missing 'organisation'
Missing 'asset' / with 'organisation'
Found 'asset' / Missing 'organization'
Found 'asset' / found 'organisation'
04-11-2022 01:47 AM
Not clear which call
clause is not required. Can you repost the entire query?
04-11-2022 02:59 AM
Sorry, I updated the last query posted. It is the full query.
All the sessions of the conference are now available online