Aerodynamika
Aerodynamika

Reputation: 8423

The magic behind Neo4J Cypher query results

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

Answers (1)

Michael Hunger
Michael Hunger

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

Related Questions