In Cypher, how can I create a relationship if it doesn't exist; update property if it does
Asked Answered
D

3

19

In Cypher in Neo4J, given two nodes, if there's no relationship between them, I'd like to create a relationship (of type Foo) with a weight property of one. If this relationship already exists, I'd like to increment its weight property.

Is there a good way to do this in a single Cypher query? Thanks!

Edit: Some additional details: The nodes are already created, unique, and in an index.

Devonne answered 6/7, 2012 at 0:33 Comment(3)
Are you okay with using a SNAPSHOT version of neo4j? In neo4j 1.8 you can update the graph using Cypher, but not in any other versions.Lail
So essentially you are looking to scan all nodes and if connected, increment, if not, create relationship?Lail
Nicholas, thanks for response. I added some additional details; the nodes are unique and indexed, so I don't think I should have to scan all the nodes. But, other than that, your comment is correct: if connected, increment, if not, create relationship.Devonne
B
46

This is exactly why we added CREATE UNIQUE in 1.8.

START a=node(...), b=node(...)
CREATE UNIQUE a-[r:CONNECTED_TO]-b
SET r.weight = coalesce(r.weight?, 0) + 1

Read more about CREATE UNIQUE here, the question mark here, and coalesce here.

Belcher answered 6/7, 2012 at 4:51 Comment(3)
Perfect! Just what I was looking for. I knew about RELATE, but not the coalesce phrase. What exactly does the "?" do?Devonne
Since Neo4j 2.0 the ? operator has been removed. See: neo4j.com/docs/snapshot/…Wappes
Create unique is now deprecated, use MERGE instead: neo4j.com/docs/developer-manual/current/cypher/clauses/mergeErotomania
F
11

To complete Andres answer, question mark at the end of a property is now an error with Neo4j 2. So request will be :

MATCH a, b
WHERE a(...) AND b(...)
CREATE UNIQUE a-[r:CONNECTED_TO]->b
SET r.weight = coalesce(r.weight, 0) + 1
Floatfeed answered 1/5, 2014 at 3:8 Comment(0)
F
5

For future reference, CREATE UNIQUE has since been deprecated (see here). It looks like you can do something similar with MATCH and MERGE:

                MATCH (a:Person {name: 'Wonder Woman'})
                MERGE (b:Person {name: 'Aries'})
                MERGE (a)-[r:FOUGHT]->(b)
                ON CREATE SET r.weight = 1
                ON MATCH SET r.weight = r.weight + 1

So here, Wonder Woman fought Aries at least once, else it will increment the weight.

Fransis answered 10/4, 2019 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.