【问题标题】:Create relationships in Neo4j在 Neo4j 中创建关系
【发布时间】:2016-06-14 15:30:27
【问题描述】:

我有一个包含大约 80 万个节点的图,我想使用 Cypher 在它们之间创建随机关系。

以下示例不起作用,因为笛卡尔积太大:

match (u),(p)
with u,p
create (u)-[:LINKS]->(p);

例如,我希望每个节点有 1 个关系 (800k),或者每个节点有 10 个关系 (8M)。

简而言之,我需要一个查询 Cypher 来统一创建节点之间的关系。 有人知道以这种方式创建关系的查询吗?

【问题讨论】:

标签: neo4j cypher relationships


【解决方案1】:

所以您希望每个节点都具有精确的x 关系?分批尝试,直到不再更新关系:

MATCH (u),(p) WHERE size((u)-[:LINKS]->(p)) < {x}
WITH u,p LIMIT 10000 WHERE rand() < 0.2 // LIMIT to 10000 then sample
CREATE (u)-[:LINKS]->(p)

【讨论】:

  • 如果节点为 800k,为什么要将 u,p 限制为 10000?为什么用 rand() 采样 20%?
  • 它不起作用,因为它为每个节点创建了很多关系。
【解决方案2】:

这应该可以工作(假设你的 neo4j 服务器有足够的内存):

MATCH (n)
WITH COLLECT(n) AS ns, COUNT(n) AS len
FOREACH (i IN RANGE(1, {numLinks}) |
  FOREACH (x IN ns |
    FOREACH(y IN [ns[TOINT(RAND()*len)]] |
      CREATE (x)-[:LINK]->(y) )));

此查询收集所有节点,并使用嵌套循环执行以下{numLinks} 次:在每个节点和随机选择的节点之间创建LINK 关系。

最里面的FOREACH 用作当前Cypher 限制的解决方法,即您不能将返回节点的操作放入节点模式中。具体来说,这是非法的:CREATE (x)-[:LINK]-&gt;(ns[TOINT(RAND()*len)])

【讨论】:

    最近更新 更多