使用foreach查询Cypher

时间:2018-01-29 15:10:55

标签: neo4j cypher

我正在尝试在具有相同密码的用户之间建立关系。我的数据如下所示:

User Pincodes
A [111,222]
B [111,333]
C [333,444]
D [111,222]

所以,我想创建A和B之间的关系,因为它们具有相同的密码和B和C之间的另一种关系。我写了类似下面的内容,这绝对不是我想要的。

MATCH (a:User),(b:User)
WHERE a.pincode=b.pincode
WITH COLLECT([a,b]) AS its
FOREACH (pincode IN its |
    CREATE (a)-[r:LIVESINSAMEAREAAS]->(b)
);

2 个答案:

答案 0 :(得分:1)

修改

来自评论:

  

我在我的问题中添加了一条新记录(请参见上文)。现在,如果我   使用您的查询,它将创建A,B和D之间的关系。   在A和D之间还有另一个常见的密码,这就是它   包含在以前的关系中。我们可以更新您的查询吗?   这包括两个不同的关系?

使用filterFOREACH的此查询应该有效:

MATCH (a:User),(b:User)
WHERE id(a) > id(b)
WITH a, b, filter(ap in a.pincodes where ap in b.pincodes) as pincodes
FOREACH (pc in pincodes | CREATE (a)-[:LIVESINSAMEAREAAS]->(b))

原始答案:

我假设pincode是一个整数列表。所以我根据你的问题创建了这个样本数据:

create (:User {pincodes : [111,222]}) 
create (:User {pincodes : [111,333]}) 
create (:User {pincodes : [333,444]})

我编写了一个查询来获取至少有一个共同pincode的所有节点。然后在这些节点之间创建关系:LIVESINSAMEAREAAS

MATCH (a:User),(b:User)
WHERE id(a) > id(b) AND ANY (ap in a.pincodes WHERE ap IN b.pincodes)
CREATE (a)-[r:LIVESINSAMEAREAAS]->(b)

WHERE(id(a) > id(b))中的第一个条件用于避免笛卡尔积和两个方向上的关系的创建。即:(a) - >(b)和(b) - >(a)。

在第二种情况下,我过滤了一对节点,a的密码列表中包含至少一个b的密码。

答案 1 :(得分:1)

虽然来自@Bruno Peres的解决方案有效,但遵循图的精神并使该区域成为单独的节点是合理的。例如:

MATCH (U:User) UNWIND U.pincodes as pincode
MERGE (A:Area {pincode: pincode})
MERGE (U)-[:liveInTheArea]->(A)
RETURN *