使 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

对上面的代码稍作修改....