Reputation: 3328
When creating two relationships with the exact same properties, I want Neo4j to update a property of the relationship based on the previous value of that property. For instance, increment a counter.
Any thoughts on how I can update the following query to achieve this?
CREATE (p:Person {name: "Tom Hanks"})
CREATE (m:Movie {title:"You've Got Mail"});
MATCH (p:Person {name: "Tom Hanks"})
MATCH (m:Movie {title:"You've Got Mail"})
CALL apoc.merge.relationship(p, "ACTED_IN",
{roles:['Joe Fox']},
{created: datetime(), counter: 0},
m,
{lastSeen: datetime(), counter: 1} // Update this to something like `counter++`
)
YIELD rel
RETURN rel;
Upvotes: 0
Views: 385
Reputation: 9284
You should first fetch the relationship using OPTIONAL MATCH
and then use the counter value from that relationship. Like this:
MATCH (p:Person {name: "Tom Hanks"})
MATCH (m:Movie {title:"You've Got Mail"})
OPTIONAL MATCH (p)-[r:ACTED_IN{roles: ['Joe Fox']}]->(m)
CALL apoc.merge.relationship(p, "ACTED_IN",
{roles:['Joe Fox']},
{created: datetime(), counter: 0},
m,
{lastSeen: datetime(), counter: r.counter + 1}
)
YIELD rel
RETURN rel;
Upvotes: 1
Reputation: 522
Here is the solution using the declarative form of Cypher:
MATCH (p:Person {name: "Tom Hanks"})
MATCH (m:Movie {title:"You've Got Mail"})
MERGE (p)-[rel:ACTED_IN {roles:['Joe Fox']}]->(m)
ON CREATE SET rel.created = datetime(), rel.counter=0
ON MATCH SET rel.lastSeen = datetime(), rel.counter=rel.counter+1
RETURN rel;
When the relationship is created, the counter is set to 0; otherwise it is updated.
Note: I took the declarative counterpart of the query from Neo4j Docs, and I added the part you're interested to.
If you are constrained or prefer using a procedural approach:
MATCH (p:Person {name: "Tom Hanks"})
MATCH (m:Movie {title:"You've Got Mail"})
CALL apoc.merge.relationship(p, "ACTED_IN",
{roles:['Joe Fox']},
{created: datetime(), counter: -1},
m,
{lastSeen: datetime()} // Update this to something like `counter++`
)
YIELD rel
SET rel.counter = rel.counter + 1
RETURN rel;
As you see, I set the initial counter to -1, so that at the end of the query it becomes 0; it is just an implementation detail, useful to avoid declaring a conditional statement between YIELD and RETURN.
Note: the YIELD instruction binds the created relationship with a name, in this case rel, in order to let you perform other modifications before the end of the query. See Neo4j Docs at the second paragraph.
Upvotes: 1