Search code examples
neo4jcypher

Cypher: how to run Cypher query with multiple update


I would like to update node property more than one time (node). How does the cypher query look like?

For example, we can update node property individually by running the below cypher query

MATCH (a:Span {id:"A"})
SET a.name = "checkout";

and

MATCH (b:Span {id:"B"})
SET b.name = "login";

separately.

But is there way to run the update together? I tried

MATCH (a:Span {id:"A"})
SET a.name = "checkout"
MATCH (b:Span {id:"B"})
SET b.name = "login";

Neo4j just throws "Neo.ClientError.Statement.SyntaxError" and does not work.


Solution

  • Your query:

    MATCH (a:Span {id:"A"})
    SET a.name = "checkout"
    MATCH (b:Span {id:"B"})
    SET b.name = "login"
    

    is not legal because "write" clauses like SET cannot be followed by a "read" clause like MATCH without an intervening WITH clause.

    But this query:

    MATCH (a:Span {id:"A"})
    SET a.name = "checkout"
    WITH 0 AS ignored
    MATCH (b:Span {id:"B"})
    SET b.name = "login";
    

    is not efficient if there can be multiple "A" nodes. For example, if there are 50 "A" nodes, then every "B" node will have its name set 50 times.

    To avoid assigning the same value to the same property multiple times, you can use aggregation to reduce N "A" rows down to just 1 row before matching "B":

    MATCH (a:Span {id:"A"})
    SET a.name = "checkout"
    WITH COUNT(*) AS ignored
    MATCH (b:Span {id:"B"})
    SET b.name = "login";
    

    Or you can use a unit subquery, which "does not change the number of rows of the enclosing query." For example, you can do this:

    CALL {
      MATCH (a:Span {id:"A"})
      SET a.name = "checkout"
    }
    MATCH (a:Span {id:"B"})
    SET a.name = "login";