【问题标题】:Adding random relationships in Neo4j only uses single node在 Neo4j 中添加随机关系只使用单个节点
【发布时间】:2019-07-06 22:33:27
【问题描述】:

我的结构是这样的:

Person   -[:HAS_HOBBY]->  Hobby

我正在生成例如500 个人节点和 20 个爱好节点随机,现在想在它们之间生成随机链接,这样每个人都有 1 个或多个爱好,但不是每个人都有相同的爱好。

CALL apoc.periodic.iterate("
    match (p:Person),(h:Hobby) with p,h limit 1000 
    where rand() < 0.1 RETURN p,h ", 
    "CREATE (p)-[:HAS_HOBBY]->(h)", 
    {batchSize: 20000, parallel: true}) 
YIELD batches, total 
RETURN *

如果没有 APOC 函数,查询看起来像这样:

MATCH(p:Person),(h:Hobby)
WITH p,h
LIMIT 10000
WHERE rand() < 0.1
CREATE (p)-[:HAS_HOBBY]->(h)

这是我尝试过的查询,问题是所有人员节点都链接到一个爱好节点,因此只使用了 1/20 个节点。

我的查询中是否缺少任何内容?或者我应该以不同的方式解决这个问题?

我还尝试了不同的方法,使用 FOREACH 子句循环遍历所有节点或通过笛卡尔积使用 SKIPLIMIT

非常感谢!

编辑:

Query 由 InverseFalcon 使用apoc.periodic.iterate

call apoc.periodic.iterate("
// first generate your range of how many hobbies you want a person to have
// for this example, 1 to 5 hobbies
WITH range(1,5) as hobbiesRange
// next get all hobies in a list
MATCH (h:Hobby)
WITH collect(h) as hobbies, hobbiesRange
MATCH (p:Person)
// randomly pick number of hobbies in the range, use that to get a number of random hobbies
WITH p, apoc.coll.randomItems(hobbies, apoc.coll.randomItem(hobbiesRange)) as hobbies
// create relationships
    RETURN p,hobbies", 
"FOREACH (hobby in hobbies | CREATE (p)-[:HAS_HOBBY]->(hobby))", 
{batchSize: 1000, parallel: false});

【问题讨论】:

    标签: neo4j cypher graph-databases


    【解决方案1】:

    在这种情况下不使用 iterate() 会更容易,而是使用一些 APOC 的集合辅助函数,例如用于从集合中获取随机项的函数。像这样的:

    // first generate your range of how many hobbies you want a person to have
    // for this example, 1 to 5 hobbies
    WITH range(1,5) as hobbiesRange
    // next get all hobies in a list
    MATCH (h:Hobby)
    WITH collect(h) as hobbies, hobbiesRange
    MATCH (p:Person)
    // randomly pick number of hobbies in the range, use that to get a number of random hobbies
    WITH p, apoc.coll.randomItems(hobbies, apoc.coll.randomItem(hobbiesRange)) as hobbies
    // create relationships
    FOREACH (hobby in hobbies | CREATE (p)-[:HAS_HOBBY]->(hobby))
    

    【讨论】:

    • 非常感谢,感谢辛苦了!我不得不使用带有apoc.periodic.iterate 的查询,因为它无法处理具有 10 个爱好的 200.000 个人节点的负载。我将在我的问题中发布使用apoc.periodic.iterate 包装的代码
    【解决方案2】:

    您的查询是正确的,除了限制它应该是 10000 而不是 1000。(最好不要使用限制)。 它对我有用,为 500 个人和 20 个爱好创建了近 1000 个关系(随机个人和爱好)。

    如果您使用它来批量执行此操作,则将批量大小设置为 1000 而不是限制 1000。您的 WHERE 条件会将关系的数量限制为 Person 和 Hobby 所有可能组合的大约 10%。 这里500x20=1000,所以会有大约1000的关系。

    注意:使用限制 1000 将仅与第一个创建关系 两个爱好。

    限制 500 只使用一个爱好,限制 1000 前两个,限制 1500 前 3 等等(500 是人数)。

    【讨论】:

      猜你喜欢
      • 2018-09-10
      • 2013-02-06
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      相关资源
      最近更新 更多