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.

Create relationship using if...else condition

Hi!

I'm very new to Neo4j. I have searched in the community and StackOverflow but I couldn't get the exact answer yet so posting it here. I am trying to create a relationship between 2 different node labels using 2 properties. Lets say my node labels are -

I:Inventory
O:Owners

Both I and O have common properties (p1 and p2). I want to be able to create a relationship (I) -[OWNED_BY]->(O) where I.p1 = O.p1 or I.p2 = O.p2.
The problem with this is it creates duplicate relationships for I when it has both p1 and p2 values. My requirement is to ignore I nodes when both p1 and p2 are null and then create only one relationship using either p1 or p2.

Thanks!

9 REPLIES 9

Bennu
Graph Fellow

Hi @karthik.shetty,

Have you tried Merge instead of create while doing the relation?

H

Hello @karthik.shetty and welcome to the Neo4j community

It will create the relation only where both properties are equal and when both exists that's to say when they are not null

MATCH (I:Inventory) MATCH (O:Owners)
WHERE I.p1 = O.p1
AND I.p2 = O.p2
AND EXISTS(I.p1)
AND EXISTS(I.p2)
MERGE (I)-[OWNED_BY]->(O)

Regards,
Cobra

Thanks Cobra and Harold! I appreciate your response.

I did give this a try and it seems to be working for a small test set of data. Which is great!!!
BTW - I do have p1 and p2 in all the I:Inventory nodes but some of them are just null string (' '). So I slightly modified the query to this - please correct me if this doesn't look right

MATCH (I:Inventory) MATCH (O:Owners) WHERE I.p1 = O.p1 AND I.p2 = O.p2 AND I.p1 <> ' ' AND O.p2 <> ' ' MERGE (I)-[:OWNED_BY]->(O)

Also, the total Inventory nodes count would be in ~ 3 millions and I am looking at the solution to do it in batch wise so I am planning to use apoc.periodic.iterate like below. - please correct me if this is not the right approach.

CALL apoc.periodic.iterate("MATCH (I:Inventory) MATCH (O:Owners) WHERE I.p1 = O.p1 AND I.p2 = O.p2 AND I.p1 <> ' ' AND O.p2 <> ' ' RETURN I, O","MERGE (I)-[:OWNED_BY]->(O)",{batchSize:10000, parallel:false})

Thanks in advance!

You are right, I didn't know your database was so big CALL apoc.periodic.iterate() is the right choice Good job!

I am sorry to bother you guys again. I am trying to setup another relationship where I want to validate one of the properties of node label P:Products p3 first then match with I.p4 = P.p4 OR I.p5 = P.p5.. Here is the query I tried but it did create relationships by ignoring my p3 condition

call apoc.periodic.iterate("match (I:Inventory) (P:Products) where I.p3 <> '0' AND I.p4= P.p4 OR I.p5 = P.p5 return I,P","merge (I) -[:PRODUCES]->(P)",{batchSize:10000, parallel:false})

Am I missing something here ? Thanks in advance!

Yes it's because of the OR, so must specify your AND condition to both parts

call apoc.periodic.iterate("
    MATCH (I:Inventory) (P:Products)
    WHERE I.p3 <> '0' AND I.p4 = P.p4
    OR I.p3 <> '0' AND I.p5 = P.p5
    RETURN I,P
    ","
    MERGE (I) -[:PRODUCES]->(P)
    ",{batchSize:10000, parallel:false})

And make sure your p3 property is a string and not an integer

First of all Thanks! I am a bit confused with this modified query. Could you please elaborate?
Not all my I nodes have values for p4 and p5. Some have p4 while p5 is a null string and vice versa. In rare cases, I have both p4 and p5 values. But I don't need to create relationships using both of them. Just either one is sufficient.
Similarly, my P nodes also have null p4 and p5.
This is why I chose to go with OR. I was under the impression that OR would pick either p4 or p5 from both I and P. Looks like my understanding is incorrect. Do you think your query would satisfy my requirement? Thanks!

It's the same query, I just added I.p3 <> '0' to both part of the OR:

(I.p3 <> '0' AND I.p4 = P.p4) OR (I.p3 <> '0' AND I.p5 = P.p5)

I'm trying to solve your p3 issue:)

ah I see. I am testing this against my data. let me see what I get back with.. thanks!