Reputation: 354
I have a cypher query that returns some results
MATCH (nodeFrom0:Z{})-[r1:FLOWS_TO]->(nodeTo1:A{})
MATCH (nodeTo1:A{})-[r2:FLOWS_TO]->(nodeTo2:A{})
MATCH (nodeTo2:A{})-[r3:FLOWS_TO]->(nodeTo3:A{})
MATCH (nodeTo3:A{})-[r4:FLOWS_TO]->(nodeTo4:B{})
MATCH (nodeTo4:B{})-[r5:FLOWS_TO]->(nodeTo5:C{})
MATCH (nodeTo5:C{})-[r6:FLOWS_TO]->(nodeTo6:B{})
MATCH (nodeTo4:B{})-[r7:FLOWS_TO]->(nodeTo7:D{})
MATCH (nodeTo7:D{})-[r8:FLOWS_TO]->(nodeTo6:B{})
MATCH (nodeTo6:B{})-[r9:FLOWS_TO]->(nodeTo8:E{})
RETURN nodeFrom0, nodeTo1, nodeTo2, nodeTo3, nodeTo4, nodeTo5, nodeTo6, nodeTo7, nodeTo8
But I dont want to reuse a variable name, and identify the same nodes based on Id and use a new variable, How can I do that
Tried
MATCH (nodeFrom0:Z{}) -[nodeRelation0:FLOWS_TO]-> (nodeTo0:A{})
MATCH (nodeFrom1:A{id: nodeTo0.id}) -[nodeRelation1:FLOWS_TO]-> (nodeTo1:A{})
MATCH (nodeFrom2:A{id: nodeTo1.id}) -[nodeRelation2:FLOWS_TO]-> (nodeTo2:A{})
MATCH (nodeFrom3:A{id: nodeTo2.id}) -[nodeRelation3:FLOWS_TO]-> (nodeTo3:B{})
MATCH (nodeFrom4:B{id: nodeTo3.id}) -[nodeRelation4:FLOWS_TO]-> (nodeTo4:C{})
MATCH (nodeFrom5:C{id: nodeTo4.id}) -[nodeRelation5:FLOWS_TO]-> (nodeTo5:B{})
MATCH (nodeFrom6:B{id: nodeTo5.id}) -[nodeRelation6:FLOWS_TO]-> (nodeTo6:D{})
MATCH (nodeFrom7:D{id: nodeTo6.id}) -[nodeRelation7:FLOWS_TO]-> (nodeTo7:B{})
MATCH (nodeFrom8:B{id: nodeTo7.id}) -[nodeRelation8:FLOWS_TO]-> (nodeTo8:E{})
return nodeFrom0,nodeRelation0,nodeTo0,nodeFrom1,nodeRelation1,nodeTo1,nodeFrom2,nodeRelation2,nodeTo2,nodeFrom3,nodeRelation3,nodeTo3,nodeFrom4,nodeRelation4,nodeTo4,nodeFrom5,nodeRelation5,nodeTo5,nodeFrom6,nodeRelation6,nodeTo6,nodeFrom7,nodeRelation7,nodeTo7,nodeFrom8,nodeRelation8,nodeTo8
Here basically id of nodeTo1 and nodeFrom2 are same eventually nodes are same. But my second query doesn't return any result.
The reason being, I am generating this query reading a json of relations, [{node1:xxxx, relation:xxxx, node2:xxxx},{node1:xxxx, relation:xxxx, node2:xxxx}]
so if the Id of node2 of one json matches the id of node1 I can treat it as same node, but with different variable name, coz it will be code generated
And The cypher query from this should also return the similar form output.
Upvotes: 0
Views: 59
Reputation: 66957
Generating independent relationship queries (as in you second query) causes inefficient Cypher, since you would have to scan for the same start/end nodes multiple times. That is not a "graphy" approach. Instead, it would be much faster to preprocess the raw data so that you generate Cypher that reuses the nodes already found, allowing neo4j to quickly leverage relationships to find subsequent nodes in a path (without any scanning).
What you want to generate is something similar to this:
MATCH
(nodeFrom0:Z)
-[:FLOWS_TO]->(nodeTo1:A{id: 1})
-[:FLOWS_TO]->(nodeTo2:A{id: 2})
-[:FLOWS_TO]->(nodeTo3:A{id: 3})
-[:FLOWS_TO]->(nodeTo4:B{id: 4})
-[:FLOWS_TO]->(nodeTo5:C{id: 5})
-[:FLOWS_TO]->(nodeTo6:B{id: 6}),
(nodeTo4)
-[:FLOWS_TO]->(nodeTo7:D{id: 7})
-[:FLOWS_TO]->(nodeTo6)
-[:FLOWS_TO]->(nodeTo8:E{id: 8})
RETURN nodeFrom0, nodeTo1, nodeTo2, nodeTo3, nodeTo4, nodeTo5, nodeTo6, nodeTo7, nodeTo8
or at least this:
MATCH
(nodeFrom0:Z)-[:FLOWS_TO]->(nodeTo1:A{id: 1}),
(nodeTo1)-[:FLOWS_TO]->(nodeTo2:A{id: 2}),
(nodeTo2)-[:FLOWS_TO]->(nodeTo3:A{id: 3}),
(nodeTo3)-[:FLOWS_TO]->(nodeTo4:B{id: 4}),
(nodeTo4)-[:FLOWS_TO]->(nodeTo5:C{id: 5}),
(nodeTo5)-[:FLOWS_TO]->(nodeTo6:B{id: 6}),
(nodeTo4)-[:FLOWS_TO]->(nodeTo7:D{id: 7}),
(nodeTo7)-[:FLOWS_TO]->(nodeTo6),
(nodeTo6)-[:FLOWS_TO]->(nodeTo8:E{id: 8})
RETURN nodeFrom0, nodeTo1, nodeTo2, nodeTo3, nodeTo4, nodeTo5, nodeTo6, nodeTo7, nodeTo8
Here is another approach that returns paths, which include both nodes and relationships:
MATCH
p1=(nodeFrom0:Z)
-[:FLOWS_TO]->(nodeTo1:A{id: 1})
-[:FLOWS_TO]->(nodeTo2:A{id: 2})
-[:FLOWS_TO]->(nodeTo3:A{id: 3})
-[:FLOWS_TO]->(nodeTo4:B{id: 4})
-[:FLOWS_TO]->(nodeTo5:C{id: 5})
-[:FLOWS_TO]->(nodeTo6:B{id: 6}),
p2=(nodeTo4)
-[:FLOWS_TO]->(nodeTo7:D{id: 7})
-[:FLOWS_TO]->(nodeTo6)
-[:FLOWS_TO]->(nodeTo8:E{id: 8})
RETURN p1, p2
Upvotes: 1