根据共享相同电话号码的列表节点在帐户节点之间创建关系

时间:2018-09-13 21:33:05

标签: neo4j cypher

我有2个帐户节点和几个列表节点,如下所示。 Match语句导致显示2个帐户,并且每个帐户都与该帐户相关联。

我想做的是根据其中至少有一个共享相同电话号码的列表中的一个创建两个帐户之间的关系。

如果可能的话,我想查看绘制的两个帐户节点之间的关系以及两个列表之间的关系,只要列表来自不同的帐户即可。

MERGE (:Account {account_id:11})
MERGE (:Listing {account_id:11, listing_id:1001, phone:99468320, author:'Paul'})

MERGE (:Account {account_id:12})
MERGE (:Listing {account_id:12, listing_id:1002, phone:97412521, author:'Sam'})
MERGE (:Listing {account_id:12, listing_id:1003, phone:97412521, author:'Sam'})
MERGE (:Listing {account_id:12, listing_id:1004, phone:99468320, author:'Sam'})
MERGE (:Listing {account_id:12, listing_id:1004, phone:0, author:'Same'})


MATCH (a:Account),(l:Listing)
WHERE a.account_id = l.account_id
CREATE (a)-[:LISTING]->(l)
RETURN a,l;

对于后者,我确实尝试了以下操作,但由于将每个具有相同编号的列表彼此链接在一起,因此只有在account_id不同的情况下才这样做,这有点发疯。

match (p1:Listing)
with p1
match (p2:Listing)
where p2.phone = p1.phone and p1 <> p2
merge(p1)-[r:SHARED_PHONE]-(p2)
RETURN p1, p2

1 个答案:

答案 0 :(得分:0)

首先,您应该仔细考虑是否确实需要SHARED_PHONE关系,因为每次添加,删除或更改电话号码时,您都必须更新这些关系。这会使很多查询复杂化,并使数据库不必要地变慢。另外,您可能会遇到许多SHARED_PHONE关系(您可能并不需要)。除了创建关系之外,您可以考虑将相关查询合并到具有相同电话号码的节点中。

但是,如果您确定自己确实需要这种关系,这是一种实现所需目标的方法:

[已更新]

MATCH (n: Listing)
WITH n.phone AS phone, COLLECT(n) AS ns
FOREACH(i IN RANGE(0, SIZE(ns)-2) |
  FOREACH(x IN [ns[i]] |
    FOREACH(y IN [z IN ns[i+1..] WHERE x.account_id <> z.account_id] |
      MERGE (x)-[:SHARED_PHONE]-(y) 
    )))

WITH子句收集共享同一Listing的所有(唯一)phone节点,并且嵌套的FOREACH子句执行最少数量的{{1} }以确保通过MERGE关系(在任一方向)连接所有适当的节点。最里面的SHARED_PHONE还可以确保要连接的节点没有相同的FOREACH