spd
spd

Reputation: 354

Using multiple variables for single neo4j node

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

Answers (1)

cybersam
cybersam

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

Related Questions