How to create a tree structure with multiple relationships?

For example, I create multiple Tweet nodes, these tweet nodes have id,reply_to id and retweet_id. Assuming I have 6 nodes. The code below shows the nodes I create.

CREATE (n:Tweet:Node {id:'123', title:'A'});
CREATE (cl:TweetLeaf:Node {id:'234', title:'IT Team', reply_to:'123'});
CREATE (cl:TweetLeaf:Node {id:'testingTeam', title:'TESTING Team', reply_to:'234'});
CREATE (cl:TweetLeaf:Node {id:'588', title:'TESTING Team', reply_to:'testingTeam'});
CREATE (cl:TweetLeaf:Node {id:'kk', title:'TESTING Team', retweet_to:'588'});
CREATE (cl:TweetLeaf:Node {id:'119', title:'TESTING Team', retweet_to:'kk'});

2.Now I would like to create a hierarchy tree and trying to create two relationships. Here is the code I tried, but the relationship retweet can not be created successfully.

CREATE (n:Tweet:Node {id:'123', title:'A'});
CREATE (cl:TweetLeaf:Node {id:'234', title:'IT Team', reply_to:'123'});
CREATE (cl:TweetLeaf:Node {id:'testingTeam', title:'TESTING Team', reply_to:'234'});
CREATE (cl:TweetLeaf:Node {id:'588', title:'TESTING Team', reply_to:'testingTeam'});
CREATE (cl:TweetLeaf:Node {id:'kk', title:'TESTING Team', retweet_to:'588'});
CREATE (cl:TweetLeaf:Node {id:'119', title:'TESTING Team', retweet_to:'kk'});

MATCH (c: TweetLeaf)
WHERE NOT (c)-[:reply_to]->() or not (c)-[:retweet]->()
MATCH (parent:Node {id:c.reply_to}),(retweet:Node {id:c.retweet_id})
CREATE (c)-[:reply_to]->(parent),(c)-[:retweet]->(retweet)



Only a partial answer and I still don't have a full understanding of the cause.

The simplest issue is that you're using retweet_id in your MATCH but retweet_to in your CREATE.

However that still doesn't solve the problem. Because reply_to and retweet_to are mutually exclusive it's preventing a MATCH. I wish I could explain this better, I'm seeing the behavior but don't have the full understanding.

Anyway if you separate the creation of retweet relationships creation from the reply_to it does work. I'd have to work with it more to get an understanding of how they can be combined into a single pass.

Not sure if this is just an example or this is how your model is constructed. If this is your model I suggest you don't carry the retweet_to or reply_to IDs as properties of the leaf. Load/Create relationships right from that start.

Try this:

CREATE (n:Tweet {id:'123', title:'A'})
CREATE (cl1:TweetLeaf {id:'234', title:'IT Team', reply_to:'123'})
CREATE (cl2:TweetLeaf {id:'testingTeam', title:'TESTING Team', reply_to:'234'})
CREATE (cl3:TweetLeaf {id:'588', title:'TESTING Team', reply_to:'testingTeam'})
CREATE (cl4:TweetLeaf {id:'kk', title:'TESTING Team', retweet_to:'588'})
CREATE (cl5:TweetLeaf {id:'119', title:'TESTING Team', retweet_to:'kk'})

CREATE (n:Tweet:Node {id:'588', title:'B'})

MATCH (c: TweetLeaf)
WHERE NOT (c)-[:reply_to]->() or not (c)-[:retweet_to]->()

MATCH (parent:Tweet {id:c.reply_to})
WITH parent, c
MERGE (c)-[:reply_to]->(parent)

MATCH (c: TweetLeaf)
WHERE NOT (c)-[:reply_to]->() or not (c)-[:retweet_to]->()

MATCH (retweet:Tweet {id:c.retweet_to})
WITH c, retweet
MERGE (c)-[:retweet_to]->(retweet)

Result:
Screen Shot 2020-10-12 at 9.53.46 AM

Thanks so much :slight_smile:

Thanks for your reply. The solution should work for you. Let me know if you need any further help.

You can build a graph like that using the approach, you described with some minor fixes. Are you looking to visualize Neo4j differently? Browser is a "network" view, but there's a host of UI options https://neo4j.com/developer/tools-graph-visualization/

I used the first eight numbers as id in this solution.

MERGE (n:Tweet {id:'13084664', title:'A'})

MERGE (cl1:TweetLeaf {id:'13085170', title:'AB', reply_to:'13084664'})

MERGE (cl2:TweetLeaf {id:'13085179', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl2:TweetLeaf {id:'13085352', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl4:TweetLeaf {id:'13085443', title:'TESTING Team', retweet_to:'13085352'})

MERGE (cl5:TweetLeaf {id:'13085356', title:'TESTING Team', retweet_to:'13085352'})

//parent and leaf.....
MATCH (parent:Tweet)
MATCH (c:TweetLeaf)
WHERE NOT (c)-[r]->() 
AND parent.id = c.reply_to
WITH parent, c
MERGE (c)-[:reply_to]->(parent)
//RETURN c, parent

//leaf to leaf reply_to.....
MATCH (c1:TweetLeaf)-[]-()
WHERE exists (c1.reply_to)

MATCH (d1:TweetLeaf)
WHERE NOT (d1)-[]->() and exists (d1.reply_to)
AND c1.id = d1.reply_to

WITH c1, d1
MERGE (d1)-[:reply_to]->(c1)
//RETURN c1, d1

//leaf to leaf retweet_to....
MATCH (c2:TweetLeaf)
WHERE exists (c2.retweet_to)
AND NOT (c2)-[]->()

MATCH (d2:TweetLeaf)-[]->()
WHERE d2.id = c2.retweet_to

WITH c2, d2
MERGE (c2)-[:retweet_to]->(d2)
//RETURN c2, d2

Result:
Screen Shot 2020-10-13 at 11.10.24 AM

Thank you so much :slight_smile:

I think you made some mistakes on the code, WHERE NOT (c)-[r]->() should be WHERE NOT (c)-[:reply_to]->(). I used your code but my output is slightly different. The root Tweet node is not linked to the coresponding child node. Could you please tell me why this could happen? Probably I made some mistakes. Thank you so much

Please post your Cypher query that produced the above result.
Thanks

MY query :

MERGE (n:Tweet {id:'13084664', title:'A'})

MERGE (cl1:TweetLeaf {id:'13085170', title:'AB', reply_to:'13084664'})

MERGE (cl2:TweetLeaf {id:'13085179', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl2:TweetLeaf {id:'13085352', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl4:TweetLeaf {id:'13085443', title:'TESTING Team', retweet_to:'13085352'})

MERGE (cl5:TweetLeaf {id:'13085356', title:'TESTING Team', retweet_to:'13085352'});

MATCH (parent:Tweet)
MATCH (c:TweetLeaf)
WHERE NOT (c)-[:reply_to]->()
AND parent.id = c.reply_to
WITH parent, c
MERGE (c)-[:reply_to]->(parent)

MATCH (c1:TweetLeaf)--()
WHERE exists (c1.reply_to)

MATCH (d1:TweetLeaf)
WHERE NOT (d1)-->() and exists (d1.reply_to)
AND c1.id = d1.reply_to

WITH c1, d1
MERGE (d1)-[:reply_to]->(c1)
//RETURN c1, d1

//leaf to leaf retweet_to....
MATCH (c2:TweetLeaf)
WHERE exists (c2.retweet_to)
AND NOT (c2)-->()

MATCH (d2:TweetLeaf)-->()
WHERE d2.id = c2.retweet_to

WITH c2, d2
MERGE (c2)-[:retweet_to]->(d2)

Hi, ameyasoft. Thank for helping me. I post the the cypher query. Please to check it. Thank you so much

MERGE (n:Tweet {id:'13084664', title:'A'})

MERGE (cl1:TweetLeaf {id:'13085170', title:'AB', reply_to:'13084664'})

MERGE (cl2:TweetLeaf {id:'13085179', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl2:TweetLeaf {id:'13085352', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl4:TweetLeaf {id:'13085443', title:'TESTING Team', retweet_to:'13085352'})

MERGE (cl5:TweetLeaf {id:'13085356', title:'TESTING Team', retweet_to:'13085352'})

[/quote]

MY query :

MERGE (n:Tweet {id:'13084664', title:'A'})

MERGE (cl1:TweetLeaf {id:'13085170', title:'AB', reply_to:'13084664'})

MERGE (cl2:TweetLeaf {id:'13085179', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl2:TweetLeaf {id:'13085352', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl4:TweetLeaf {id:'13085443', title:'TESTING Team', retweet_to:'13085352'})

MERGE (cl5:TweetLeaf {id:'13085356', title:'TESTING Team', retweet_to:'13085352'});

MATCH (parent:Tweet)
MATCH (c:TweetLeaf)
WHERE NOT (c)-[:reply_to]->() 
AND parent.id = c.reply_to
WITH parent, c
MERGE (c)-[:reply_to]->(parent)

MATCH (c1:TweetLeaf)-[]-()
WHERE exists (c1.reply_to)

MATCH (d1:TweetLeaf)
WHERE NOT (d1)-[]->() and exists (d1.reply_to)
AND c1.id = d1.reply_to

WITH c1, d1
MERGE (d1)-[:reply_to]->(c1)
//RETURN c1, d1

//leaf to leaf retweet_to....
MATCH (c2:TweetLeaf)
WHERE exists (c2.retweet_to)
AND NOT (c2)-[]->()

MATCH (d2:TweetLeaf)-[]->()
WHERE d2.id = c2.retweet_to

WITH c2, d2
MERGE (c2)-[:retweet_to]->(d2)
Sorry my mistake. A typo!  
The variable 'l2' is used twice. The fourth line should have the variable as 'l3' instead of 'l2'. Here is the corrected Cypher:

MERGE (n:Tweet {id:'13084664', title:'A'})

MERGE (cl1:TweetLeaf {id:'13085170', title:'AB', reply_to:'13084664'})

MERGE (cl2:TweetLeaf {id:'13085179', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl3:TweetLeaf {id:'13085352', title:'TESTING Team', reply_to:'13085170'})

MERGE (cl4:TweetLeaf {id:'13085443', title:'TESTING Team', retweet_to:'13085352'})

MERGE (cl5:TweetLeaf {id:'13085356', title:'TESTING Team', retweet_to:'13085352'});

Try and let me know.

Thank you so much, another question I would ask you, why the whole code can not be run successfully?

MATCH (parent:Tweet)
MATCH (c:TweetLeaf)
WHERE NOT (c)-[:reply_to]->() 
AND parent.id = c.reply_to
WITH parent, c
MERGE (c)-[:reply_to]->(parent)

MATCH (c1:TweetLeaf)-[]-()
WHERE exists (c1.reply_to)

MATCH (d1:TweetLeaf)
WHERE NOT (d1)-[]->() and exists (d1.reply_to)
AND c1.id = d1.reply_to

WITH c1, d1
MERGE (d1)-[:reply_to]->(c1)
//RETURN c1, d1

//leaf to leaf retweet_to....
MATCH (c2:TweetLeaf)
WHERE exists (c2.retweet_to)
AND NOT (c2)-[]->()

MATCH (d2:TweetLeaf)-[]->()
WHERE d2.id = c2.retweet_to

WITH c2, d2
MERGE (c2)-[:retweet_to]->(d2)
The errors message
WITH is required between MERGE and MATCH (line 8, column 1 (offset: 166))
"MATCH (c: TweetLeaf)"

Do I need to put ; for each query? I just copy and pasted the whole code, and try to run it.

Try this:

MATCH (parent:Tweet)
MATCH (c:TweetLeaf)
WHERE NOT (c)-[:reply_to]->() 
AND parent.id = c.reply_to
WITH parent, c
MERGE (c)-[:reply_to]->(parent)

//this is just to satisfy the syntax...not using it further down the code
WITH c

MATCH (c1:TweetLeaf)-[]-()
WHERE exists (c1.reply_to)

MATCH (d1:TweetLeaf)
WHERE NOT (d1)-[]->() and exists (d1.reply_to)
AND c1.id = d1.reply_to

WITH c1, d1
MERGE (d1)-[:reply_to]->(c1)

//this is just to satisfy the syntax...not using it further down the code
WITH c1

MATCH (c2:TweetLeaf)
WHERE exists (c2.retweet_to)
AND NOT (c2)-[]->()

MATCH (d2:TweetLeaf)-[]->()
WHERE d2.id = c2.retweet_to

WITH c2, d2
MERGE (c2)-[:retweet_to]->(d2)

This works!

Thank you so much. I really appreciated ur helping. Have a nice day :slight_smile:

I think you need to add otherwise there is no node link to Tweet node

MATCH p=(:TweetLeaf)-[*0..1]-()
RETURN p