在neo4j中的列表中存在的元素之间的所有关系

问题描述

https://community.neo4j.com/t/make-all-to-all-relationship-among-the-element-present-in-list/37390 这是同一个问题的链接

我有两列作为源和目标的 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

enter image description here

解决方法

您也可以在导入后实现这一点,而不是在导入过程中执行此类操作

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 查询字符串),或者您可以通过 CSV 执行 3 次传递:

首先通过MERGE源节点

第二次只传递 split() 和 MERGE 目标节点。

第三次通过 MATCH 来匹配源和目标并合并它们之间的关系。

,
    LOAD CSV with headers FROM 'file:///sample.csv' AS row
MERGE (n:MyNode:domain{name:row.source})
WITH row,'|'))  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

对上面的代码做了一点修改....