Cypher:更新所有特定节点列表之间的关系

时间:2014-07-25 15:05:21

标签: python neo4j cypher combinations

我正在使用 Neo4j ,我对如何在 Cypher 中执行某些查询以及保持高性能表示担忧。

我的图表中包含标签为“Thing”的节点。并且每个节点都具有属性“ pk ”(整数)

所以,给出像 [123,34,125] 这样的pks列表,我想创建/更新(如果存在)所有对的节点之间的关系我们可以得到他们的组合。

(123,34),(123,125),(32,125)并且对于每个节点之间的r设置 r.weight = 0 (如果已创建关系)或 r.weight + = 1 (如果已存在)

目前我使用itertools.combination(pks,2)在Python中进行组合,然后我为每对c1,c2执行组合:

'MATCH (c1:Thing {pk: %(c1_pk)s}), (c2:Thing {pk: %(c2_pk)s}) ' \
'CREATE UNIQUE c1-[r:KNOWS]-c2 ' \
'SET r.weight=coalesce(r.weight, 0)+1 RETURN c1, r.weight, c2' % {'c1_pk': c1_pk,
                                                                  'c2_pk': c2_pk}

但是我不喜欢为每一对调用该查询,因为当pks列表很长时性能很差,因为组合和查询将是长度(pks)*(长度(pks)-1)

我怎么能这样做?

修改 大约有15000个“Thing”节点,并且总是具有相同的数量。 并且有一个约束是pk属性唯一(t:Thing t.pk是唯一的)

1 个答案:

答案 0 :(得分:0)

您对创建这些成对关系的位置没有任何限制,因此您尝试将此作为笛卡尔产品。如果你有很多节点,它会变慢。

但是我在查询中看到的一个错误是你试图创建两次关系;让我们说你想从X创建一个关系 - >你曾经为X做过一次 - > Y,然后再次为Y - > X

你可以通过只做一次一次来减少一半,如下所示:

MATCH (c1:Thing {pk: %(c1_pk)s}), (c2:Thing {pk: %(c2_pk)s}) 
CREATE UNIQUE c1-[r:KNOWS]-c2 
SET r.weight=coalesce(r.weight, 0)+1 RETURN c1, r.weight, c2' % {'c1_pk': c1_pk,
                                                                  'c2_pk': c2_pk}
WHERE c1.id < c2.id

请注意,我们按ID排序节点。由于它们都有不同的ID,因此您可以执行X - &gt; Y,但不是Y - &gt; X

这使得整个过程从长度(pks)*长度(pks)-1变为:(长度(pks)*长度(pks)-1)/ 2。

但是,没有办法解决你想要做的事情是O(n ^ 2)