![](/img/trans.png)
[英]Neo4j cypher query to search node having a relation with specific node and same relation with other node as well
[英]cypher narrow search with same node property
我的问题在这里: 密码如何在两个节点之间以及与起始节点之间的距离之间建立关系 ,此处有更多详细信息:200万家公司,每个公司必须且仅属于到领先的公司(称为组),因此每个节点都具有以下属性:groupId和companyId; 而且,不同组中的公司可能有关系。 问题:给定一个groupId和领先公司ID,返回该组中的所有关系以及该组中与领先公司最短距离的每个节点。
由于anwser的sql有很大的性能问题,尤其是shortPath,所以我的问题是使用shortPath时,我们可以缩小搜索范围,仅搜索具有相同属性的节点吗?
还是有其他方法可以解决原始问题?
抱歉,由于我在中国大陆,无法访问console.neo4j.com(即使使用VPN),因此我将示例放在这里:
create (a :COMPANY {companyId:"a",groupId:"ag"}),
(b:COMPANY {companyId:"b",groupId:"ag"}),
(c:COMPANY {companyId:"c",groupId:"ag"}),
(d:COMPANY {companyId:"d",groupId:"ag"}),
(e:COMPANY {companyId:"e",groupId:"eg"})
create (a)-[:INVESTMENT]->(b),
(b)-[:INVESTMENT]->(c),
(c)-[:INVESTMENT]->(d),
(a)-[:INVESTMENT]->(c),
(d)-[:INVESTMENT]->(b),
(c)-[:INVESTMENT]->(e)
return *
这里的节点a,b,c,d
是同一组,而a
是领导公司, e
是另一组,但与c
有关系。 所以我想获得ag
组中的节点-节点关系,例如: ab,ac,bc,cd,db
以及从a
到组成员的最短距离,例如,返回dist.a=0,dist.b=1,dist.c=1,dist.d=2
我认为这无法借助纯密码解决。 您可以通过在关系中添加临时属性并应用Dijkstra算法来尝试使用APOC库。
输入参数:
{
"groupId": "ag",
"leadingCompany": "a"
}
查询:
// Search for a leading company
MATCH (lc:COMPANY {companyId: $leadingCompany, groupId: $groupId})
WITH lc,
apoc.create.uuid() as tmpProp // Temporary property name
// All relationships in the group are found.
// And the value of the temporary property is set ..
MATCH (c1:COMPANY {groupId: $groupId})-[r:INVESTMENT]->(c2:COMPANY {groupId: $groupId})
CALL apoc.create.setRelProperty(r, tmpProp, 1) yield rel
WITH lc, tmpProp,
count(r) as tmp
// For each node in the group, need to find short paths to the leading company
MATCH (c:COMPANY {groupId: $groupId})
CALL apoc.algo.dijkstraWithDefaultWeight(lc, c, 'INVESTMENT', tmpProp, 2000000) yield path
WITH tmpProp, c,
min(length(path)) as distanceToLeading
// All paths in the group are found, and the temporary property is deleted
MATCH (c)-[r:INVESTMENT]->(:COMPANY {groupId: $groupId})
CALL apoc.create.removeRelProperties(r, [tmpProp]) yield rel
RETURN c as groupNode, distanceToLeading,
collect(r) as groupRelations
APOC过程可以在这里提供帮助,因为一些路径扩展器过程可以用来查找到组中每个节点的最短距离,还有一个cover()
过程可以找到一组节点之间的所有关系。
您需要确保首先在:Company(groupId)和:Company(companyId)上具有索引。
MATCH (c:Company{groupId:$groupId})
WITH collect(c) as companies
WITH companies, [c in companies | id(c)] as companyIds, [c in companies
WHERE NOT (c)<-[:INVESTMENT]-(:Company{groupId:$groupId})][0] as lead
// for the above, if you already know the lead companyId, just MATCH to the lead instead of this filter
CALL apoc.algo.cover(companyIds) YIELD rel
WITH companies, lead, collect(rel {start:startNode(rel).companyId, end:endNode(rel).companyId}) as relationships
UNWIND companies as company
MATCH path = shortestPath((lead)-[:INVESTMENT*]->(company))
WHERE all(node in nodes(path) WHERE node in companies)
RETURN relationships, collect(company {.companyId, distance:length(path)}) as distance
此查询将为您提供所需的输出:
match p=((c:COMPANY{companyId:'a'})-[i:INVESTMENT*0..99]->(l:COMPANY))
where l.groupId=c.groupId
with c,i,l,nodes(p) as path order by c.companyId
with c,l,collect(distinct l.companyId) as Companies,min(size(path))-1 as Dist
match pp=shortestpath((cc:COMPANY{companyId:'a'})-[ii:INVESTMENT*0..99]->(ll:COMPANY))
where ll.companyId in Companies
with c,Companies,Dist,reduce(s='',x in nodes(pp)|s + x.companyId ) as CompanyPath
return c.companyId,Companies,Dist,CompanyPath order by Dist
您会注意到,它不需要groupId的高级知识。 如果一家牵头公司可以分为两组,那么您需要将其包括在初始位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.