Search code examples
neo4jcypherneo4j-apoc

Neo4j add property to relationship when using apoc.merge.relationship()


I have the following import:

// NO ATTACHMENT OR LINK
USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM ("file:///sessions/Hourly_Parsed/2019-12-10_00_hourly_parsed_mail_logs.csv") AS row
MERGE (a:Sender { name: row.From, domain: row.Sender_Sub_Fld, datetime: datetime(replace(row.DateTime, ' ', 'T'))})
MERGE (b:Recipient { name: row.To, datetime: datetime(replace(row.DateTime, ' ', 'T'))})
WITH a,b,row
WHERE row.Url = "false" AND row.FileHash = "false"
CALL apoc.merge.relationship(a, row.Outcome2, {}, {}, b) YIELD rel as rel1
RETURN a,b

As you can see I have added the datetime property to both the Sender and Recipient nodes. I would like to add this property to the relationship. The problem that I am running into is that my property is created using apoc.merge.relationship() so that I can create the name based on the outcome in the rows column.

Can I add something below the CALL portion to add the datetime: datetime(replace(row.DateTime, ' ', 'T')) as a property to the relationship?


Solution

  • You can add properties to relationships in the same apoc.merge.relationship call. Here is the signature of that apoc call:

    apoc.merge.relationship(startNode :: NODE?, relationshipType :: STRING?, identProps :: MAP?, props :: MAP?, endNode :: NODE?, onMatchProps = {} :: MAP?) :: (rel :: RELATIONSHIP?)

    So this should work for you:

    CALL apoc.merge.relationship(a, row.Outcome2, {}, {datetime:datetime(replace(row.DateTime, ' ', 'T'))}, b, {})

    Remember this will add the datatime property only when a new edge gets created. If you set a property in the last argument of apoc.merge.relationship, then the property will be added on MATCH. If you want to include the property in the MATCH part of the MERGE, you can set it in the 3rd argument of apoc.merge.relationship. For example, if you run

    CALL apoc.merge.relationship(a, "CONNECTS_TO", {time: "today"}, {}, b, {})
    CALL apoc.merge.relationship(a, "CONNECTS_TO", {time: "tomorrow"}, {}, b, {})
    

    you will end up with two CONNECTS_TO edges between a and b, one with time: "today", and one with time:"tomorrow". But if you run the following instead

    CALL apoc.merge.relationship(a, "CONNECTS_TO", {}, {time: "today"}, b, {})
    CALL apoc.merge.relationship(a, "CONNECTS_TO", {}, {time: "tomorrow"}, b, {})
    

    You will end up with only one CONNECTS_TO edge that has time: "today" as its property.