Search code examples
neo4jcyphergraph-databasesneo4j-apoc

How to get a neo4j node(if it exists) having latest date and create connection with current node?


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


Solution

  • 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.