Search code examples
pythondatabaseneo4jpy2neo

How can I perform a "match or create" operation in py2neo v3?


I want to create a Node/Relationship only if a Node/Relationship with the same attributes doesn't already exist in the graph. If they do, I would like to fetch the relevant item.

Right now I am doing something that I suppose is both unidiomatic and inefficient. Assuming each Person node has a unique pair (name, age), I do something like this:

try:
    node = graph.data('MATCH (n:Person) WHERE n.name = {name} AND'
                      'n.age = {age} RETURN n LIMIT 1',
                      name=my_name, age=my_age)[0]['n']
except IndexError:
    node = Node('Person', name=my_name, age=my_age)

To my understanding find_one() works only if you have just one property to search for, and match_one() allows no properties for relationships.


Solution

  • You can use the Cypher MERGE clause to perform a "match or create":

    node = graph.data('MERGE (n:Person) WHERE n.name = {name} AND'
                      'n.age = {age} RETURN n LIMIT 1',
                      name=my_name, age=my_age)[0]['n']
    

    py2neo does have merge and merge_one functions, but they only take a single property, so using Cypher would be the more general approach.