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.

I am intending on creating on one way relation when trying to stitch child nodes their parent node

Krishna1
Node

I am trying to stitch all the child nodes that are related to parent node but apparently my code is creating 2 way relation. Can anyone please suggest any changes in my code to be able achieve one way relation

MATCH (n:user)
where n.child_id IS NOT NULL AND n.parent_id IS NOT NULL
with n.parent_id as pid, collect (n.child_id) as cid
MATCH (p:user) where p.parent_id = pid and p.child_id in cid
match (q:user) where p.parent_id = pid and q.child_id in cid and not q.child_id in p.child_id and not (p)-[:IS_RELATED]->(q)
MERGE (p)-[r:IS_RELATED]->(q);

Please find the attached screen shot for reference.

3 REPLIES 3

I think it is because your 'p' and 'q' nodes match to the same thing, thus you get relationships in each direction. 

I am not sure of your data model. I assume that your are using parent_id and child_in to create relationships between parent and child after importing, as you would use relationships to relate the parent and its children, versus a 'join' type query by finding nodes that have matching parent and child id's. 

I am assuming the child_id represents the unique identifier for each node and the parent_id (when present) represents the node's parent, where child.parent_id = parent.child_id defined the parent/child relationship.  Based on this assumption, the following query will group the nodes and link the parent and its children.  Note, I would assume that child_id is never null since it is a primary id for the user node.  If so, that null check can be removed from line 2. 

Let me know if my assumption is incorrect, and I can adjust the query to match.

 

MATCH (child:user) 
WHERE child.child_id IS NOT NULL AND child.parent_id IS NOT NULL
WITH child.parent_id as pid, collect (child) as childNodes
MATCH (parent:user{child_id: pid})
FOREACH(child in childNodes |
    MERGE (child)-[:IS_RELATED]->(parent)
)

Screen Shot 2023-01-12 at 2.14.30 PM.png 

Screen Shot 2023-01-12 at 2.15.10 PM.png

Thanks for your quick reply. Your understanding on p, q nodes related to same label is correct. both parent and child are in same node. we need to creation relationship between same label nodes. In 5th line of the code I am just eliminating the self relationship. Could you please help me on this.

MATCH (n:user)
where n.child_id IS NOT NULL AND n.parent_id IS NOT NULL
with n.parent_id as pid, collect (n.child_id) as cid
MATCH (p:user) where p.parent_id = pid and p.child_id in cid
match (q:user) where p.parent_id = pid and q.child_id in cid and not q.child_id in p.child_id and not (p)-[:IS_RELATED]->(q)
MERGE (p)-[r:IS_RELATED]->(q);

you are getting the two reversed relationships per pair of nodes because p and q look to be elements of the list of child nodes. 

What was wrong with my query?  Its not clear how the parent and child nodes are related. Will you please explain?  I assumed the each node has a unique identifier specified by its child_id. Each child node has parent_id node that indicates is parent's child_id value, thus child.parent_id = parent_child_id. Is this correct?  If so, the query I provided should work. I can point out what is the issue with your query if you can clarify the relationships between nodes and their parent_id and child_id values.