我有一个包含1,000个公司,1,000个人员和2,000个银行帐户的数据库。我想将每个公司的一个银行帐户与每个人的一个银行(没有银行帐户)与多个实体进行随机配对。
我尝试了以下操作但未成功:
MATCH (a:PERSON), (b:BANK_ACCOUNT)
WHERE NOT (a)-[:HAS_BANK_ACCOUNT]->(:BANK_ACCOUNT)
AND NOT (b)<-[:HAS_BANK_ACCOUNT]-(:COMPANY|:PERSON)
MERGE (a)-[:HAS_BANK_ACCOUNT]->(b);
MATCH (COMPANY), (b:BANK_ACCOUNT)
WHERE NOT (a)-[:HAS_BANK_ACCOUNT]->(:BANK_ACCOUNT)
AND NOT (b)<-[:HAS_BANK_ACCOUNT]-(:COMPANY|:PERSON)
MERGE (a)-[:HAS_BANK_ACCOUNT]->(b);
你能帮忙吗?
最好
答案 0 :(得分:1)
如何使用APOC rock_n_roll
// iterate over people
// and create a relationship to one bank
// that does not already have the HAS_BANK_ACCOUNT
CALL apoc.periodic.rock_n_roll(
'MATCH (a:PERSON)
WHERE NOT (a)-[:HAS_BANK_ACCOUNT]->()
RETURN a AS a',
'WITH {a} AS a MATCH (b:BANK_ACCOUNT)
WHERE NOT (b)<-[:HAS_BANK_ACCOUNT]->()
WITH a, b
LIMIT 1
MERGE (a)-[:HAS_BANK_ACCOUNT]->(b)',
100
)
// repeat, but for companies this time
CALL apoc.periodic.rock_n_roll(
'MATCH (a:COMPANY)
WHERE NOT (a)-[:HAS_BANK_ACCOUNT]->()
RETURN a AS a',
'WITH {a} AS a
MATCH (b:BANK_ACCOUNT)
WHERE NOT (b)<-[:HAS_BANK_ACCOUNT]->()
WITH a, b
LIMIT 1
MERGE (a)-[:HAS_BANK_ACCOUNT]->(b)',
100
)
或者,只需稍作更改,您也可以一遍完成
CALL apoc.periodic.rock_n_roll(
'MATCH (a)
WHERE a:PERSON or a:COMPANY
AND NOT (a)-[:HAS_BANK_ACCOUNT]->()
RETURN a AS a',
'WITH {a} AS a
MATCH (b:BANK_ACCOUNT)
WHERE NOT (b)<-[:HAS_BANK_ACCOUNT]->()
WITH a, b
LIMIT 1
MERGE (a)-[:HAS_BANK_ACCOUNT]->(b)',
100
)
如果您想使关系比添加关系的顺序更随机,则可以使用一行来随机化行驶MATCH语句。
CALL apoc.periodic.rock_n_roll(
'MATCH (a)
WHERE a:PERSON or a:COMPANY
AND NOT (a)-[:HAS_BANK_ACCOUNT]->()
RETURN a AS a, rand() AS random
ORDER BY random',
'WITH {a} AS a
MATCH (b:BANK_ACCOUNT)
WHERE NOT (b)<-[:HAS_BANK_ACCOUNT]->()
WITH a, b, rand() AS random
ORDER BY random
LIMIT 1
MERGE (a)-[:HAS_BANK_ACCOUNT]->(b)',
100
)
答案 1 :(得分:1)
节点太少,您应该可以使用APOC收集功能进行混洗和压缩来轻松地做到这一点:
MATCH (b:BANK_ACCOUNT)
WITH collect(b) as accounts
WITH apoc.coll.shuffle(accounts) as accounts
MATCH (p:PERSON)
WITH accounts, collect(p) as persons
UNWIND apoc.coll.zip(persons, accounts[..1000]) as personAccount
WITH accounts, personAccount[0] as person, personAccount[1] as account
CREATE (person)-[:HAS_BANK_ACCOUNT]->(account)
WITH distinct accounts[1000..] as accounts
MATCH (c:COMPANY)
WITH accounts, collect(c) as companies
UNWIND apoc.coll.zip(companies, accounts) as companyAccount
WITH companyAccount[0] as company, companyAccount[1] as account
CREATE (company)-[:HAS_BANK_ACCOUNT]->(account)