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

问题描述 投票:0回答:1

我有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
neo4j cypher
1个回答
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子句执行所需的最小数量的MERGEs,以确保所有适当的节点通过SHARED_PHONE关系(在任一方向上)连接。最里面的FOREACH还确保要连接的节点不具有相同的account_id

© www.soinside.com 2019 - 2024. All rights reserved.