1

我有csv一个包含一对多关系的文件,其中每个 type 元素A由一个或多个 type 元素组成,B但每个元素B仅指一个 type 元素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 抱怨第一个查询是无用的,还是第二个查询有有效的好处?

4

1 回答 1

2

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

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

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

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

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

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

于 2019-05-29T18:13:50.343 回答