NEO4J MERGE is not working as expected

439 views Asked by At

I am new in neo4j and I am having problems with the MERGE clause. I have a method to do queries like this:

def upsert (idValue, valueField1):
   query = "MERGE (n:Node {id: '" + idValue+ "'}) "
   query += "ON MATCH SET n.field1= n.field1+ " + str(valueField1) + " "
   query += "ON CREATE SET n = {id: '" + idValue + "', field1: 0} "
   return db.run(query)

Then, I am calling the method like this:

upsert("1", 0)
upsert("2", 0)
upsert("3", 5)
upsert("1", 2)
upsert("1", 1)

So, afterthat, I expected this:

node (id="1", field1=3)
node (id="2", field1=0)
node (id="3", field1=0)

But, I am getting this:

node (id="1", field1=2)
node (id="2", field1=0)
node (id="3", field1=0)

In addition, If I do the same calls again, I got this:

node (id="1", field1=4)
node (id="2", field1=0)
node (id="3", field1=5)

Could anyone explain me what is happening and what am I doing wrong please? I was looking for on internet, but I couldn't find anything helpful for me.

1

There are 1 answers

1
logisima On

With this query, that is exactly the same as what you are doing, I have the good result :

WITH [
        {idValue:'1', valueField1:0},
        {idValue:'2', valueField1:0},
        {idValue:'3', valueField1:5},
        {idValue:'1', valueField1:2},
        {idValue:'1', valueField1:1}
    ] AS data
UNWIND data AS item
MERGE (n:Node {id:item.idValue}) 
  ON MATCH SET n.field1= n.field1 + item.valueField1
  ON CREATE SET n = {id:item.idValue, field1: 0}

And then with MATCH (n:Node) RETURN n.id, n.field1 ORDER BY n.id LIMIT 25 :

n.id    n.field1
"1"     3
"2"     0
"3"     0

So I don't think that the problem comes from the query itself, but from its construction.

You should consider to use a parameterized query. It will be easier to read the query, but also code it and it's more performant in Neo4j. So your code should be :

def upsert (idValue, valueField1):
   query = "MERGE (n:Node {id:$id}) "
           " ON MATCH SET n.field1= n.field1 + $value"
           " ON CREATE SET n = {id:$id, field1: 0}"
   return db.run(query, id=idValue, value=valueField1)