Neo4j Cypher 查询的解释相同,但仅针对一个查询生成警告



>我有csv包含一对多关系的文件,其中A类型的每个元素都由一个或多个类型B的元素组成,但B的每个元素仅引用一个类型A的元素。

举个例子:

A   |  B   
-------------
a1  |  b1
a1  |  b2
a1  |  b3
a2  |  b4

我已经在 neo4j 图中创建了节点,现在我想为这些关系创建一个边缘。

我以为这个查询

LOAD CSV WITH HEADERS FROM "file:///file.csv" AS row
WITH row
MATCH (n:A {A_ID: row.a_id}), (t:B {BID : row.b_id})
MERGE (n)-[:HAS_CONNECTION]->(t);

但 Neo4j 会提示以下警告:

此查询在断开连接的模式之间构建笛卡尔乘积。 如果查询的一部分包含多个断开连接的模式,则此 将在所有这些部分之间构建一个笛卡尔乘积。这可能会 产生大量数据并减慢查询处理速度。而 偶尔有意,通常可以重新制定 避免使用此交叉乘积的查询,可能通过添加 不同部分之间的关系或使用OPTIONAL MATCH(identifier is: (t))

所以我把它改成:

LOAD CSV WITH HEADERS FROM "file:///file.csv" AS row
WITH row
MATCH (t:B {BID : row.b_id})
WITH row, t
MATCH (n:A {AID: row.a_id})
MERGE (n)-[:HAS_CONNECTION]->(t);

Neo4j没有抱怨。

但是,如果我EXPLAIN这两个查询,则结果是相同的。

neo4j抱怨第一个查询是无用的,还是第二个查询有实际的好处?

虽然警告为真,但查询确实构建了一个笛卡尔乘积,这在本例中很好,因为这正是您想要的,即使它们没有连接,也会nt,并且在任何情况下基数都会很低(如果这些是唯一节点,则可能是 1)。

忽略警告并保留您的第一个查询,当您执行类似操作时,其中每个变量的预期节点数为 1,或者至少很小。

至于为什么警告没有出现在第二个计划中,这可能只是对生成警告的内容的限制。这些仍然是等效的,同样的事情也适用。

只是为了注意警告的真正原因,这是为了防止您执行以下操作:

MATCH (a:A), (b:B)

或类似的,你最终会在所有一种节点与另一种节点之间得到一个笛卡尔乘积。当你用特定的属性(特别是唯一属性)缩小这些范围时,这只是一个 1x1 的笛卡尔乘积,没有问题。

最新更新