简体   繁体   中英

How to explain the execution path of this Cypher query?

Imagine the following graph:

在此处输入图片说明

And this query:

MATCH(p:Person {id:1})
MATCH (p)-[:KNOWS]-(s)
CREATE (p)-[:LIVE_IN]->(:Place {name: 'Some Place'})

Now, why five LIVE_IN , Place are created even though s is not involved in the CREATE statement? is there any place in the docs that explain this behavior?

Note: this is not about MERGE vs CREATE , although MERGE can solve it.

EDIT: In response to @Tomaz answer: I have deliberately placed MATCH (p)-[:KNOWS]-(s) in the query and I know how it will behave. I am asking for found explanations. For example, is CREATE will execute for each path or row in the matched patterns regardless of the node involved in the CREATE ? what if you have complex matched patterns such as, disconnected graph, Trees...etc?

Also note that the direction of relationship KNOWS ( - vs -> ) will effect the number of returned rows (9 vs 1), but CREATE will execute five times regardless of the direction.

Update:

I have added 3 other node Office and issued the following query:

MATCH(p:Person {id:1})
MATCH (p)-[:KNOWS]-(s)
MATCH (o:Office)
CREATE (p)-[:LOVE]->(:Place {name: 'Any Place'})

And as result: 15 LOVE Place have been created, so it seems to me that cypher performs Cartesian Product between all nodes:

p refer to 1 nodes, s refer to 5 nodes, o refer to 3 nodes => 1 * 5 * 3 = 15

But I can not confirm this form neo4j docs unfortunately.

This is because the Person with id 1 has five neighbors.

In your query you start with:

MATCH(p:Person {id:1})

This produces a single row, where it finds the node you are looking for. The next step is:

MATCH (p)-[:KNOWS]-(s)

This statement found 5 neighbors, so your cardinality or number of rows increases to five. And then you run a create statement for each row, which in turn creates five Places. You could for example lower the cardinality back to 1 before doing the CREATE and you'll create only a single place:

MATCH(p:Person {id:1})
MATCH (p)-[:KNOWS]-(s)
// aggregation reduces cardinality to 1
WITH p, collect(s) as neighbors
CREATE (p)-[:LIVE_IN]->(:Place {name: 'Some Place'})

When doing cypher query, always have in mind the cardinality you are operating.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM