1

I am trying to maintain a series of data nodes in neo4j using cypher. So i am creating a node with current date and timestamp. I also need to create a connection between current and most recent node. So I need to check if nodes already exists if they do then get the node with latest date and create (latest:Node)<-[:next]-(prev:Node). If the nodes does not exist then just create a node with current date. Thanks

4

1 回答 1

4

It would be easier to maintain this if you had a :Head node of some sort that points to the most recent node. Not only would this help you find the most recent node fast (constant time no matter how many nodes are in the list), it would help coordinate concurrent changes to this list.

Let's assume a single :Head node with a :Latest relationship to the most recent node. We need to lock on the :Head node before we check for the most recent node to avoid race conditions when concurrent queries are executing.

Easiest way to do this is with APOC Procedures with call apoc.lock.nodes().

// assume `latest` node with latest timestamp is already created and in scope
WITH latest
MATCH (head:Head)
CALL apoc.lock.nodes([head]) // avoid race conditions
OPTIONAL MATCH (head)-[r:LATEST]->(prev)
WITH latest, head, r, prev // this + the WHERE needed to halt query if latest isn't newer than prev
WHERE COALESCE(prev.timestamp, 0) < latest.timestamp
DELETE r // update :LATEST relationship
MERGE (head)-[:LATEST]->(latest)
WITH latest, prev
WHERE prev IS NOT NULL // protects from error in case when prev is null
MERGE (latest)<-[:next]-(prev)

Keep in mind that while this will work when the newly created node is now the most recent node, it won't work for nodes that are not newer than prev. In this case, they would not be added to the list; you would need to modify the query to insert the node in the proper place in the list.

于 2017-12-01T23:16:28.687 回答