Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-07-2021 05:31 PM
I am currently trying to dump a live data source into neo4j. Here is an example of what I need to achieve:
Given a json that represents an item:
{"id": "0001", "category_id": "a1", "shop_id": "shop_x1"}
The database has the following 3 types nodes: Item, Category, Shop, each with unique ID.
I need to:
(1) create the Item node with ID "0001" if a node with the same id does not exist;
(2) replace the relationship (Item)->(Category), that is this item can only points to at most one category,
if the json field "category_id" is empty, then the resulting Item node should have no relationship to Category
(3) similarly, replace the relationship (Item)->(Shop); keep no relationship if "shop_id" is empty.
So far what I have come up with is the following:
UNWIND $batch as row
MERGE (i:Item {id: row.id})
SET i += row
REMOVE i.category_id, i.shop_id
WITH i, row
OPTIONAL MATCH (i)-[r:IS_CATEGORY]->(c:Category)
DELETE r
WITH i, row
MATCH (c:Category {id: row.category_id})
MERGE (i)-[:IS_CATEGORY]->(c)
WITH i, row
OPTIONAL MATCH (i)-[r:IS_SHOP]->(s:Shop)
DELETE r
WITH i, row
MATCH (s:Shop {id: row.shop_id})
MERGE (i) - [:IS_SHOP] -> (s)
This script tries to merge a new Item node, then remove existing relationship followed by the creation of the new one. However it breaks loose when "category_id" or "shop_id" is empty, with error node is missing.
If I replace the OPTIONAL MATCH with normal MATCH, it again does not work when "category_id" is empty. In this case, since no category is matched, all following WITH will cease to fire.
I've no idea how to achieve this behaviour, yet this seems a fairly common requirement, namely to update a node and all its relationships. Would appreciate any help, thanks.
11-14-2021 10:28 AM
So you want to to do a conditional update?
It's not built in, if you have only one condition you can use a WHERE
to filter out the times where the property does not exists, for multiple ones you can use
FOREACH(x IN case row.category_id when null then [] else [true] | MERGE ...)
see
All the sessions of the conference are now available online