我仍在努力理解为什么我会在neo4j中为某个查询获取某种格式的笛卡尔积,而不是另一个。这就是我设置数据库的方式:
CREATE (q:Form {version: "1.0"})
CREATE (q:Question {text: "Sector de la empresa", active: true})
然后我尝试了以下查询:
MATCH
(f:Form {version: "1.0"}),
(q:Question {text: "Sector de la empresa"})
CREATE (f)-[:asks]->(q)
RETURN f, q
但是,我收到以下警告:
This query builds a cartesian product between disconnected patterns.
If a part of a query contains multiple disconnected patterns,
this will build a cartesian product between all those parts.
This may produce a large amount of data and slow down query processing.
While occasionally intended, it may often be possible to reformulate the
query that avoids the use of this cross product, perhaps by adding a
relationship between the different parts or by using OPTIONAL MATCH
(identifier is: (q))
当我使用以下查询时,它不会给我这个警告:
MATCH (f:Form {version: "1.0"})
WITH f
(q:Question {text: "Sector de la empresa"})
CREATE (f)-[:asks]->(q)
RETURN f, q
当我使用此查询时:
MATCH (f:Form {version: "1.0"})
MATCH (q:Question {text: "Sector de la empresa"})
CREATE (f)-[:asks]->(q)
RETURN f, q
我使用以下文章作为资源,但它仍未完全回答我的问题:Why does neo4j warn: "This query builds a cartesian product between disconnected patterns"?
为什么我会为某些查询格式而不是其他格式获取笛卡尔积?另外,我不完全了解笛卡尔产品警告是什么。
答案 0 :(得分:5)
如果您MATCH
在两个不同的标签上没有任何关系,那么您将收到此警告。原因是如果你这样做:
MATCH (a:Foo), (b:Bar)
找到这两个节点的所有可能组合是Neo4j的工作。因此,对于a
的第一场比赛,它将为b
的每场比赛返回一行,对于a
的第二场比赛,它将再次为{{1}的每场比赛返回一行}, 等等。因此,您的结果中将获得b
个总行数。随着数据库的增长,这对性能非常不利。
我可以看到您正在(number of Foo nodes) x (number of Bar nodes)
version
和Form
text
进行过滤,这样会有所帮助。这甚至可以为您提供一个Question
节点和一个Form
节点。因此,只要您在Question
和Form(version)
上有索引,查询应该非常快。 Neo4j无法告诉(或者至少目前没有实现能够告诉)将返回多少行,因此它会发出警告,说明您的查询可能会很慢。
答案 1 :(得分:1)
读完你的问题后,我的密码世界崩溃了 - 所有三个问题都应该涉及笛卡尔积。
检查(同时the console和本地数据库 - 版本3.3.0),结果证明我是理智的 - 他们都涉及笛卡尔产品:
为什么在第一种情况下只有一个警告(仍然在版本3.3.0中我没有任何线索 - 你只需要运行计划器来解决这个问题,如果这不是警告那么警告是什么?一些愚蠢的密码逻辑?
Cypher查询由部分组成,每个部分可以是更新(写入)或读取。
就阅读部分而言,这是发生的事情:
如果你有这样的事情:
(a {name:'Bill'})-->(b:Dog)
计划可能看起来像这样。
AllNodeScan
):
name == 'bill'
)-->
关系:Dog
)重要的是,在找到(a)
时,我们需要扫描每个节点。但我们只是遍历图表,为后者找到(b)
s - no AllNodeScan
。
(有AllNodeScan
的变体,请参阅Starting Node Operators)
如果您的查询是这样的:
MATCH (f:Form {version: "1.0"}), (q:Question {text: "Sector de la empresa"})
Neo被迫对AllNodeScan
和f
进行q
- 他们之间没有模式可以遍历。这可能会创建一个f * q大小的结果集,这可能是巨大的。