我是neo4j的新手。我已经设置了一个包含大约200个节点的基本数据库,其中包括人员,地址和电话号码。
他们都可以相互链接,因此一个人可以拥有与他们相关联的电话号码和地址,但地址可以连接到电话号码,电话号码可以链接到电话号码,人们可以链接到人,等
我希望能够搜索节点集群,例如我想要返回所有连接的节点,例如:
对于上述每个结果,可以找到多个结果,我想找到一个链接上述每个中至少一个的集群(最初为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
我一无所获。
我要问的是,我知道这个人,联系和地址,他们是否以任何方式联系?
答案 0 :(得分:0)
这些查询可能会让您入门。
除此之外:我建议您针对不同类型的关系使用不同的关系类型(例如HAS_ADDRESS
,HAS_CONTACT
和KNOWS
)。这将使您的查询更容易理解,并最终可以帮助您加快查询速度(因为您可以简化它们)。
要查找任何姓氏为“James”的人,他以任何方式与以“0123”开头的联系人相关联:
MATCH path=(p:person)-[*]-(c:contact)
WHERE
p.Surname = "James" AND
c.Contact =~ "0123.*"
RETURN p,c
要查找任何姓氏为“James”且以任何方式连接到以“0123”开头的联系人的人,只要他们之间的路径包含邮政编码为“ab11ab”的地址:< / p>
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
要查找任何姓氏为“James”的人,他们以任何方式与邮政编码为“ab11ab”的地址相关联,只要他们之间的路径包含以“0123”开头的联系人:< / p>
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
找到任何姓氏“詹姆斯”的人,他们以任何方式连接到邮编为“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
答案 1 :(得分:0)
如果我理解正确,那么你应该获得一系列必需的节点,然后找到所有人与所有人连接的路径。
// 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