在 Neo4j 中添加随机关系仅使用单个节点
Adding random relationships in Neo4j only uses single node
我的结构如下所示:
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)
这是我试过的查询,问题是所有人员节点都链接到一个 hobby 节点,因此只使用了 1/20 个节点。
我的查询中是否缺少任何内容?或者我应该以不同的方式解决这个问题?
我还尝试了不同的方法,其中 FOREACH
子句遍历所有节点或使用 SKIP
和 LIMIT
通过笛卡尔积
非常感谢!
编辑:
由 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});
你的查询是正确的,除了 limit 它应该是 10000 而不是 1000。(最好不要使用 limit)。
它对我有用,并为 500 个人和 20 个爱好建立了近 1000 种关系(随机的人和爱好)。
如果您使用它来批量执行此操作,则将批量大小设置为 1000 而不是限制 1000。您的 WHERE 条件会将关系的数量限制为 Person 和 Hobby 所有可能组合的大约 10%。
这里500x20=1000,所以会有大约1000个关系。
NOTE: Using limit 1000 will create relationships only with the first
two Hobbies.
限制 500 只使用一个爱好,限制 1000 前两个,限制 1500 前 3 等等(500 是人数)。
在这种情况下不使用 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))
我的结构如下所示:
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)
这是我试过的查询,问题是所有人员节点都链接到一个 hobby 节点,因此只使用了 1/20 个节点。
我的查询中是否缺少任何内容?或者我应该以不同的方式解决这个问题?
我还尝试了不同的方法,其中 FOREACH
子句遍历所有节点或使用 SKIP
和 LIMIT
通过笛卡尔积
非常感谢!
编辑:
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});
你的查询是正确的,除了 limit 它应该是 10000 而不是 1000。(最好不要使用 limit)。 它对我有用,并为 500 个人和 20 个爱好建立了近 1000 种关系(随机的人和爱好)。
如果您使用它来批量执行此操作,则将批量大小设置为 1000 而不是限制 1000。您的 WHERE 条件会将关系的数量限制为 Person 和 Hobby 所有可能组合的大约 10%。 这里500x20=1000,所以会有大约1000个关系。
NOTE: Using limit 1000 will create relationships only with the first two Hobbies.
限制 500 只使用一个爱好,限制 1000 前两个,限制 1500 前 3 等等(500 是人数)。
在这种情况下不使用 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))