我的问题在于:cypher-how-get-relation-between-every-two-node-and-the-distance-from-start-node,更多细节:200万家公司,每家公司必须且只属于一家名为group的领先公司,因此每个节点都有属性:groupId和companyId;更重要的是,不同群体的公司可能有关系。问题:给定groupId和领先的公司ID,返回该组中的所有关系以及该组中与领先公司最短距离的每个节点。
由于sw表示anwser有很大的性能问题,特别是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
组中获取节点 - 节点关系,例如:a-b,a-c,b-c,c-d,d-b
以及从a
到组成员的最短距离,例如,返回dist.a=0,dist.b=1,dist.c=1,dist.d=2
答案 0 :(得分:0)
我认为在纯密码的帮助下无法解决这个问题。您可以通过向关系添加临时属性并应用Dijkstra algorithm来尝试使用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
答案 1 :(得分:0)
APOC程序可以在这里提供帮助,因为一些路径扩展程序可用于查找到组中每个节点的最短距离,还有一个cover()
程序可以找到所有一组节点之间的关系。
您希望确保首先拥有索引:公司(groupId)和:公司(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
答案 2 :(得分:0)
此查询将为您提供所需的输出:
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的高级知识。如果牵头公司可以分为两组,则需要将其包含在最初的位置。