簡體   English   中英

具有相同節點屬性的密碼窄搜索

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM