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.

Newtang
  • 6,414
  • 10
  • 49
  • 70
  • 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. – Nicholas Jul 06 '12 at 00:35
  • So essentially you are looking to scan all nodes and if connected, increment, if not, create relationship? – Nicholas Jul 06 '12 at 02:48
  • 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. – Newtang Jul 06 '12 at 04:20

3 Answers3

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.

Andres
  • 1,454
  • 11
  • 12
  • Perfect! Just what I was looking for. I knew about RELATE, but not the coalesce phrase. What exactly does the "?" do? – Newtang Jul 06 '12 at 06:03
  • 5
    Since Neo4j 2.0 the ? operator has been removed. See: http://neo4j.com/docs/snapshot/query-operators.html#query-operators-comparison – Stefan Ollinger Oct 27 '14 at 13:39
  • 1
    Create unique is now deprecated, use MERGE instead: http://neo4j.com/docs/developer-manual/current/cypher/clauses/merge/ – Ashallar Nov 27 '17 at 14:26
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
Blackus
  • 6,883
  • 5
  • 40
  • 51
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.