搜索一个任意的链接节点neo4j的群集



我是neo4j的新手。我已经设置了一个基本的DB,其中大约有200个节点,这些节点包括其他人,地址和电话号码。

他们都可以互相链接,因此一个人可以拥有与他们关联的电话号码和地址,但是可以将地址连接到电话号码,电话号码可以链接到电话号码,与人,人们,人们,人,等

我希望能够搜索一个节点群,例如我想返回任何连接的节点,例如:

  • 一个人的姓詹姆斯,
  • 另一个人有琼斯的姓氏,
  • 一个包含123456的电话号码
  • AB11AB邮政编码的地址

可以找到上述多个结果,我想找到一个群集,该群集至少链接上述每个结果(最初是1级,但最终可配置的级别)。我不在乎它们是如何链接的。

此外,可能有4个以上的项目需要搜索(用户配置)

我已经尝试单独搜索它们,然后尝试将它们结合并将它们集合在一起,但是我似乎无法正确地掌握逻辑。

一些返回相关节点的简单查询(以了解我的数据):

MATCH (p:person {Surname:"james"}) RETURN a
MATCH (a:address {Postcode:"ab11ab"}) RETURN p

这是可能的吗?

任何帮助都将受到欢迎。

谢谢,

乔恩

群集可能不是最好的术语,也许是sub Graph ??

这是场景:

CREATE (I1:person {description:'John James', FirstName:'John', Surname:'James'})
CREATE (I2:address {description:'1 Test Street ab11ab', Postcode:'ab11ab'})
CREATE (I3:contact {description:'01234567890 home telephone', Contact:'01234567890'})

CREATE (I4:person {description:'Frank James', FirstName:'Frank', Surname:'James'})
CREATE (I5:contact {description:'01234567899 home telephone', Contact:'01234567899'})

CREATE (I6:person {description:'Bert James', FirstName:'Frank', Surname:'James'})
CREATE (I7:person {description:'Brenda James', FirstName:'Brenda', Surname:'James'})
CREATE (I8:person {description:'Violet James', FirstName:'Violet', Surname:'James'})
CREATE (I9:address {description:'75 Test Street ab11ab', Postcode:'ab11ab'})
CREATE (I1)-[:LinkedTo]->(I2)
CREATE (I2)-[:LinkedTo]->(I3)
CREATE (I4)-[:LinkedTo]->(I5)
CREATE (I6)-[:LinkedTo]->(I7)
CREATE (I7)-[:LinkedTo]->(I8)
CREATE (I7)-[:LinkedTo]->(I9)

如果我运行以下内容:

MATCH (p:person)--(a:address)--(c:contact) 
    where p.Surname = "James"   AND 
          a.Postcode = "ab11ab" AND 
          c.Contact =~ "0123.*"  
RETURN p,a,c

我得到了我想要的群集。但是,如果我更改链接的顺序:

MATCH (p:person)--(c:contact)--(a:address) 
    where p.Surname = "James"   AND 
          a.Postcode = "ab11ab" AND 
          c.Contact =~ "0123.*"  
RETURN p,a,c

我什么都没得到。

我问的是我认识这个人,联系和地址,他们是否以任何方式链接?

如果我正确理解,那么您应该得到一系列所需的节点,然后找到所有与每个人都连接的路径。

// Get an array of all matching nodes:
OPTIONAL MATCH (p:person {Surname: "James"})
    WITH COLLECT(p) AS  c1
OPTIONAL MATCH (a:address {Postcode:"ab11ab"}) 
    WITH COLLECT(a)+c1 AS c2
OPTIONAL MATCH (c:contact) WHERE c.Contact =~ "0123.*" 
    WITH COLLECT(c)+c2 AS nodes
// Take the Cartesian product:
UNWIND nodes AS n1
  UNWIND nodes AS n2
      // Get path:
      MATCH p = (n1)-[*]-(n2) 
          WHERE ANY(n IN nodes WHERE n IN NODES(p) AND NOT n IN [n1,n2])
RETURN p

这些查询可能会让您开始。

一边:我建议您使用不同类型的关系使用不同的关系类型(例如HAS_ADDRESSHAS_CONTACTKNOWS)。这将使您的查询更容易理解,并最终可以帮助您加快查询(因为您可以简化它们)。

  1. 找到任何姓氏"詹姆斯"的人,他们以任何方式连接到以" 0123"开头的联系人:

    MATCH path=(p:person)-[*]-(c:contact) 
    WHERE
      p.Surname = "James"   AND 
      c.Contact =~ "0123.*"
    RETURN p,c
    
  2. 找到任何姓氏"詹姆斯"的人,他们以任何方式连接到以" 0123"开头的联系人,只要它们之间的路径包括一个地址,其邮政编码为" ab11ab":

    MATCH path=(p:person)-[*]-(c:contact) 
    WHERE
      p.Surname = "James"   AND 
      c.Contact =~ "0123.*" AND
      ANY(n IN NODES(path)[1..-1] WHERE
        'address' IN LABELS(n) AND n.Postcode = "ab11ab")
    RETURN p,c
    
  3. 找到任何姓氏"詹姆斯"的人,他们以任何方式连接到邮政编码为" ab11ab"的地址,只要他们之间的路径包括一个以" 0123"开头的联系人:

    MATCH path=(p:person)-[*]-(a:address) 
    WHERE
      p.Surname = "James"   AND
      a.Postcode = "ab11ab" AND
      ANY(n IN NODES(path)[1..-1] WHERE
        'contact' IN LABELS(n) AND n.Contact =~ "0123.*")
    RETURN p,a
    
  4. 找到任何姓氏"詹姆斯"的人,他们以任何方式连接到邮政编码为" ab11ab"的地址,并且接触以" 0123"开头(这很可能在大的情况下很慢。DB):

    MATCH (p:person {Surname: "James"})
    OPTIONAL MATCH path1 = (p)-[*]-(c:contact) 
    WHERE c.Contact =~ "0123.*"
    WITH p, c,
      [n IN NODES(path1)[1..-1] WHERE 'address' IN LABELS(n) AND n.Postcode = "ab11ab"] AS addrs
    OPTIONAL MATCH path2 = (p)-[*]-(a:address) 
    WHERE a.Postcode = "ab11ab"
    WITH p, c, addrs + a AS addrs,
      [n IN NODES(path2)[1..-1] WHERE 'contact' IN LABELS(n) AND n.Contact =~ "0123.*"] AS conts
    WITH p, addrs, conts + c AS conts
    UNWIND conts AS cont
    WITH p, addrs, COLLECT(DISTINCT cont) AS conts
    WHERE SIZE(conts) > 0
    UNWIND addrs AS addr
    WITH p, conts, COLLECT(DISTINCT addr) AS addrs
    WHERE SIZE(addrs) > 0
    RETURN p, conts, addrs
    

最新更新