cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Update a value of a key in a relationship

lx2pwnd
Node Clone

Hi, I want to ask you if there is a way to update just a value of a key in a relationship. I have relationships in my graph where each one has a label "emails_exchanges" and actually my code is:

        if graph.match((originLblMatcher, targetLblMatcher), "SEND_MAIL"):
            rel = graph.evaluate("MATCH (n:Person {name:\'" + originLbl + "\'})-[r:SEND_MAIL]->(m:Person {name:\'" + targetLbl + "\'}) return r")
            count = rel["emails_exchanged"] + 1
            graph.create(Relationship(originLblMatcher, "SEND_MAIL", targetLblMatcher, emails_exchanged=count))

        else:
            emails_exchanged = 1
            graph.create(Relationship(originLblMatcher, "SEND_MAIL", targetLblMatcher, emails_exchanged=emails_exchanged))

Is there a method to update just the "email_exchanged" value instead of recreate the entire relationship?
thanks

1 ACCEPTED SOLUTION

Hello, first of all "emails_exchanges" isn't a label, it's a property key (labels are specific to nodes only, not relationships).

Also it looks like you're using...Python? It helps to tell us what programming language you're using in addition to Cypher, if applicable.

What you're looking for is using SET to set the value of a relationship property, though in this case it would be better to use MERGE on the relationship (which will create it if it doesn't already exist), allowing you to use ON MATCH and ON CREATE to decide what to set depending on if the MERGE matched on existing relationships or instead created a new one between the nodes. You can do this directly through your Cypher:

"MATCH (n:Person {name:\'" + originLbl + "\'}), (m:Person {name:\'" + targetLbl + "\'})
MERGE (n)-[r:SEND_MAIL]->(m)
ON CREATE SET r.emails_exchanged = 1
ON MATCH SET r.emails_exchanged = r.emails_exchanged + 1
RETURN r"

If you expect this to be called concurrently, you may need to use atomic increment proc from APOC Procedures to ensure there are no race conditions between the read and update of the property:

"MATCH (n:Person {name:\'" + originLbl + "\'}), (m:Person {name:\'" + targetLbl + "\'})
MERGE (n)-[r:SEND_MAIL]->(m)
ON CREATE SET r.emails_exchanged = 0
WITH r
CALL apoc.atomic.add(r, 'emails_exchanged', 1) YIELD newValue
RETURN r"

View solution in original post

3 REPLIES 3

Hello, first of all "emails_exchanges" isn't a label, it's a property key (labels are specific to nodes only, not relationships).

Also it looks like you're using...Python? It helps to tell us what programming language you're using in addition to Cypher, if applicable.

What you're looking for is using SET to set the value of a relationship property, though in this case it would be better to use MERGE on the relationship (which will create it if it doesn't already exist), allowing you to use ON MATCH and ON CREATE to decide what to set depending on if the MERGE matched on existing relationships or instead created a new one between the nodes. You can do this directly through your Cypher:

"MATCH (n:Person {name:\'" + originLbl + "\'}), (m:Person {name:\'" + targetLbl + "\'})
MERGE (n)-[r:SEND_MAIL]->(m)
ON CREATE SET r.emails_exchanged = 1
ON MATCH SET r.emails_exchanged = r.emails_exchanged + 1
RETURN r"

If you expect this to be called concurrently, you may need to use atomic increment proc from APOC Procedures to ensure there are no race conditions between the read and update of the property:

"MATCH (n:Person {name:\'" + originLbl + "\'}), (m:Person {name:\'" + targetLbl + "\'})
MERGE (n)-[r:SEND_MAIL]->(m)
ON CREATE SET r.emails_exchanged = 0
WITH r
CALL apoc.atomic.add(r, 'emails_exchanged', 1) YIELD newValue
RETURN r"

Thanks for your help. Anyway, yes, I'm using python and py2neo in my application. I have used your solution e it's working perfectly. Sorry for the noob question, but i don't know neo4j and chyper
so well

Not a problem, all part of the learning process!