Reputation: 8423
I have the following query in Neo4J Cypher 2.0:
MATCH (u:User{uid:'1111111'}), (c1:Concept), (c2:Concept),
c1-[:BY]->u, c2-[:BY]->u, c1-[rel:TO]->c2
WITH c1,c2,rel
MATCH c1-[:AT]->ctx, c2-[:AT]-ctx
WHERE ctx.uid = rel.context
RETURN c1.uid AS source_id, c1.name AS source_name,
c2.uid AS target_id, c2.name AS target_name,
rel.uid AS edge_id,
rel.context AS context_id, ctx.name AS context_name;
What it does is that it looks for all the nodes of the Concept
label (c1
and c2
) connected to User
node u
, finds their (c1
to c2
) connections to one another (rel
), then it tries to find which different contexts (ctx
) those concept nodes (c1
and c2
) appear in, but only those, whose uid
matches the uid
of the .context
property of the relationships rel
(rel.context
) and then returns them in a table, where we have the source id
and name
, the target id
and name
, the connection id
, as well as the .context
id
property of that relation and the name of the context with that id
.
So all works fine, but the question is: WHY?
I mean how does Cypher matches so neatly the right ctx.uid
to the right rel.context
to know that it should be inserted exactly at the right place of the results table?
Can somebody explain me the magic behind this?
Or am I completely wrong and just getting messy results?
Thank you!
Upvotes: 0
Views: 222
Reputation: 41706
It creates a pattern-graph that represents your combined match patterns. And then it uses indexes to find bound nodes that it starts to apply the pattern graph to and returns a result row for every match found.
While applying the pattern graph it uses your WHERE conditions to filter out paths that you don't want eagerly as early as possible.
If it can't find bound nodes it has to go over all nodes of a label (like :Concept) or over all nodes of the graph (if you haven't specify any label or lookup condition).
Upvotes: 1