我有一个csv
文件,其中包含一对多关系,其中类型A
的每个元素由一个或多个类型B
的元素组成,但每个{{1 }}仅引用B
类型的一个元素。
一个例子:
A
我已经在neo4j图中创建了节点,现在我想为这些关系创建边。
我以为这个查询
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);
OPTIONAL MATCH
所以我将其更改为:
(identifier is: (t))
Neo4j没有抱怨。
但是,如果我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是无用的抱怨第一个查询还是第二个查询有有效的好处?
答案 0 :(得分:2)
虽然警告为true,但是查询确实会建立笛卡尔积,在这种情况下很好,因为这正是您想要的n
和t
,即使它们没有连接,并且在任何情况下基数都较低(如果这些是唯一节点,则可能为1)。
在执行此类操作(其中每个变量的预期节点数为1或至少很小)时,请忽略警告并保留第一个查询。
关于为什么警告没有出现在第二个计划中,这很可能只是对生成警告的目的的限制。这些仍然等效,并且同样适用。
仅需注意警告的真正原因,这是为了防止您执行以下操作:
MATCH (a:A), (b:B)
或类似,在这种情况下,您最终将在一种节点的所有节点与另一种节点的所有节点之间形成笛卡尔乘积。当您使用只是1x1笛卡尔积的特定属性(尤其是唯一属性)缩小这些范围时,就没有问题。