在从CSV导入数据后,我认为两种实体Gene和Chromosome之间的关系,我认为这是简单而正常的方式:
MATCH (g:Gene),(c:Chromosome)
WHERE g.chromosomeID = c.chromosomeID
CREATE (g)-[:PART_OF]->(c);
然而,当我这样做时,neo4j(浏览器用户界面)抱怨道:
此查询在断开连接的模式之间构建笛卡尔积。 如果查询的一部分包含多个断开连接的模式,这将在所有这些部分之间构建笛卡尔积。这可能会产生大量数据并减慢查询处理速度。虽然偶尔会有意图,但通常可以重新制定避免使用此交叉产品的查询,可能是通过在不同部分之间添加关系或使用OPTIONAL MATCH(标识符为:(c))。 < / p>
我不知道问题所在。 chromosomeID是一个非常简单的外键。
答案 0 :(得分:34)
浏览器告诉你:
Gene
实例和每个Chromosome
实例之间进行比较来处理您的查询。如果您的数据库具有G
基因和C
染色体,那么查询的复杂性为O(GC)
。例如,如果我们正在使用人类基因组,那么有46条染色体和25000个基因,因此数据库必须进行1150000
比较。您可以通过更改查询来提高复杂性(和性能)。例如,如果我们在:Gene(chromosomeID)
上created an index,并且更改了查询以便我们最初只匹配具有最小基数(46条染色体)的节点,那么我们只会O(G)
(或25000
)&#34;比较&#34; - 那些比较实际上是快速索引查找!这种方法应该快得多。
创建索引后,我们可以使用此查询:
MATCH (c:Chromosome)
WITH c
MATCH (g:Gene)
WHERE g.chromosomeID = c.chromosomeID
CREATE (g)-[:PART_OF]->(c);
它使用WITH
子句强制首先执行第一个MATCH
子句,避免使用笛卡尔积。第二个MATCH
(和WHERE
)子句使用第一个MATCH
子句和索引的结果来快速获取属于每个染色体的确切基因。
答案 1 :(得分:4)
正如logisima在评论中提到的那样,这只是一个警告。匹配笛卡尔积很慢。在您的情况下,它应该没问题,因为您想要连接以前未连接的InlineFormset
和Gene
节点,并且您知道笛卡尔积的大小。没有太多的染色体和少量的基因。如果您Chromosome
,查询可能会破坏蛋白质上的基因。
我认为该警告旨在用于其他有问题的查询:
MATCH
是笛卡尔积,但您不知道是否存在关系,则可以使用MATCH
OPTIONAL MATCH
MATCH
和Gene
没有任何关系,则应该拆分查询如果您的查询花费的时间过长或未完成,这是另一个问题,提供了一些如何优化笛卡尔积的提示:How to optimize Neo4j Cypher queries with multiple node matches (Cartesian Product)