使 neo4j 中列表中存在的元素之间的所有关系
Make all to all relationship among the element present in list in neo4j
https://community.neo4j.com/t/make-all-to-all-relationship-among-the-element-present-in-list/37390
这是同一个问题link
我有一个包含两列作为源和目标的 csv 文件。
我需要在每个源的目标列中的所有元素之间建立所有关系。
这是我的查询,我无法建立所有对所有的关系。
LOAD CSV with headers FROM 'file:///sample.csv' AS row
unwind (split(row.target,'|')) as target
merge (n:MyNode{name:row.source})
merge (m:MyNode{name:target})
merge (m) -[:TO{weight:row.weight}]->(n)
merge (m) -[:r]-(m) // not sure about this line
您也可以在导入之后实现,而不是在导入期间通过这样做
match (s:Source)-[:TO]-(t:Target)
with s, collect (t) as targets
unwind targets as target
foreach (n in targets | merge (n)-[:r]-(target))
不幸的是,计划中的 Eager 操作会使这变得复杂,使您无法使用 USING PERIODIC COMMIT LOAD CSV(处理任何大型 CSV 都需要它)。
(有关 Eager behavior here 的更多信息)
在 Neo4j 4.1 或 4.2 中,您可以使用子查询来解决这个问题,但这不适用于 4.3 及更高版本。
有子查询:
LOAD CSV with headers FROM 'file:///sample.csv' AS row
MERGE (n:MyNode{name:row.source})
WITH row, n
CALL {
WITH row, n
UNWIND (split(row.target,'|')) as target
MERGE (m:MyNode{name:target})
MERGE (m) -[:TO{weight:row.weight}]->(n)
WITH collect(m) as targets
UNWIND targets as t1
UNWIND targets as t2
WITH t1, t2
WHERE id(t1) < id(t2)
MERGE (t1)-[:r]-(t2)
RETURN true as result
}
RETURN result
对于 4.0 及以下版本,子查询不可用,而对于版本 4.3.x(尚未发布)及更高版本,子查询不再是 Eager 运算符的解决方法,因此这将不起作用。
相反,您可以使用 apoc.cypher.doIt()
代替子查询,这将解决 Eager(但您必须使用 Cypher 查询字符串),或者您可以通过您的 3 次传递CSV:
先传到MERGE源节点
第二次传递到仅 split() 并合并目标节点。
第三遍匹配源和目标并合并它们之间的关系。
LOAD CSV with headers FROM 'file:///sample.csv' AS row
MERGE (n:MyNode:domain{name:row.source})
WITH row, n
CALL {
WITH row, n
UNWIND (split(row.target,'|')) as target
MERGE (m:MyNode:token{name:target})
MERGE (m) -[:TO{weight:row.weight}]->(n)
WITH collect(m) as targets
UNWIND targets as t1
UNWIND targets as t2
WITH t1, t2
WHERE id(t1) < id(t2)
MERGE (t1)-[:token_join]-(t2)
RETURN true as result
}
WITH n
CALL{
WITH n
match (d1:domain)
match (d2:domain)
WITH d1,d2
WHERE id(d1) < id(d2)
MERGE (d1)-[:domain_join]-(d2)
return true as result
}
match (nodes) return nodes
对上面的代码稍作修改....
https://community.neo4j.com/t/make-all-to-all-relationship-among-the-element-present-in-list/37390 这是同一个问题link
我有一个包含两列作为源和目标的 csv 文件。 我需要在每个源的目标列中的所有元素之间建立所有关系。
这是我的查询,我无法建立所有对所有的关系。
LOAD CSV with headers FROM 'file:///sample.csv' AS row
unwind (split(row.target,'|')) as target
merge (n:MyNode{name:row.source})
merge (m:MyNode{name:target})
merge (m) -[:TO{weight:row.weight}]->(n)
merge (m) -[:r]-(m) // not sure about this line
您也可以在导入之后实现,而不是在导入期间通过这样做
match (s:Source)-[:TO]-(t:Target)
with s, collect (t) as targets
unwind targets as target
foreach (n in targets | merge (n)-[:r]-(target))
不幸的是,计划中的 Eager 操作会使这变得复杂,使您无法使用 USING PERIODIC COMMIT LOAD CSV(处理任何大型 CSV 都需要它)。
(有关 Eager behavior here 的更多信息)
在 Neo4j 4.1 或 4.2 中,您可以使用子查询来解决这个问题,但这不适用于 4.3 及更高版本。
有子查询:
LOAD CSV with headers FROM 'file:///sample.csv' AS row
MERGE (n:MyNode{name:row.source})
WITH row, n
CALL {
WITH row, n
UNWIND (split(row.target,'|')) as target
MERGE (m:MyNode{name:target})
MERGE (m) -[:TO{weight:row.weight}]->(n)
WITH collect(m) as targets
UNWIND targets as t1
UNWIND targets as t2
WITH t1, t2
WHERE id(t1) < id(t2)
MERGE (t1)-[:r]-(t2)
RETURN true as result
}
RETURN result
对于 4.0 及以下版本,子查询不可用,而对于版本 4.3.x(尚未发布)及更高版本,子查询不再是 Eager 运算符的解决方法,因此这将不起作用。
相反,您可以使用 apoc.cypher.doIt()
代替子查询,这将解决 Eager(但您必须使用 Cypher 查询字符串),或者您可以通过您的 3 次传递CSV:
先传到MERGE源节点
第二次传递到仅 split() 并合并目标节点。
第三遍匹配源和目标并合并它们之间的关系。
LOAD CSV with headers FROM 'file:///sample.csv' AS row
MERGE (n:MyNode:domain{name:row.source})
WITH row, n
CALL {
WITH row, n
UNWIND (split(row.target,'|')) as target
MERGE (m:MyNode:token{name:target})
MERGE (m) -[:TO{weight:row.weight}]->(n)
WITH collect(m) as targets
UNWIND targets as t1
UNWIND targets as t2
WITH t1, t2
WHERE id(t1) < id(t2)
MERGE (t1)-[:token_join]-(t2)
RETURN true as result
}
WITH n
CALL{
WITH n
match (d1:domain)
match (d2:domain)
WITH d1,d2
WHERE id(d1) < id(d2)
MERGE (d1)-[:domain_join]-(d2)
return true as result
}
match (nodes) return nodes
对上面的代码稍作修改....