2017-06-08 69 views
0

我認爲這是一個很長的問題,可能是一個簡單的答案。然而,我認爲明智的做法是包含完整的上下文以防萬一我的查詢邏輯有問題(如果格式沒有關閉,請諒解 - 我已經更名了變量,它可能是畸形的,我需要關於理論而不是結構的幫助)查詢/雙可選匹配問題

一個組織可以有子辦公

(o:Organisation)-[:sub_office]->(an:Organisation) 

或者總公司

(o)-[:head_office]->(ho:Organisation) 

人在不同的子辦事處可以僱員或前僱員 EX1

(o)-[:employee]->(p:Person{name:'person1'})<-[:ex_employee]-(an) 

人員可以通過管理關係與其他人相關。這些管理鏈接可以是可變長度的。 EX2

(o)-[:employee]->(p:Person{name:'person2'})-[:managed]->(p:Person{name:'person3'})<-[:ex_employee]-(an) 
(o)-[:ex_employee]->(p:Person{name:'person4'})-[:managed]->(p:Person{name:'NOT_RETURNED1'})-[:managed]->(p:Person{name:'person5'})<-[:employee]-(an) 
(o)-[:ex_employee]->(p:Person{name:'person6'})<-[:managed]-(p:Person{name:'NOT_RETURNED2'})<-[:managed]-(p:Person{name:'person8'})<-[:employee]-(an) 
(o)-[:ex_employee]->(p:Person{name:'person9'})-[:managed]->(p:Person{name:'NOT_RETURNED4'})-[:managed]->(p:Person{name:'NOT_RETURNED5'})<-[:managed]-(p:Person{name:'person11'})<-[:employee]-(an) 
.... 

我查詢: -organisation, -sub辦公室, - 如何他們相關 這些都是工作的罰款(我想...)

的問題,我與退休人員(員工或前僱員)及其與組織的關係,但只有當他們直接連接到其他組織(如EX1)或通過管理連鎖(所有EX2 - I試圖通過標記不會被查詢返回的人稱爲'NOT_RETURNED'來更清楚地說明)

我創建了以下內容:

MATCH (queryOrganisation:Organisation{name:'BigCorp'})-[orgRel]-(relatedOrganisation:Organisation) 
    WITH queryOrganisation, orgRel, relatedOrganisation 
    MATCH (queryOrganisation)-[employmentRel]->(queryPerson:Person) 
    OPTIONAL MATCH (queryPerson)<-[relatedOrgRel]-(relatedOrganisation) 
    OPTIONAL MATCH (queryPerson)-[:managed*1..]-(relatedPerson:Person)<-[relatedOrgRel]-(relatedOrganisation) 
    WITH queryOrganisation, orgRel, relatedOrganisation, employmentRel, queryPerson, relatedOrgRel, relatedPerson 
    WHERE NOT queryOrganisation.name = relatedOrganisation.name 
    RETURN ID(queryOrganisation) as queryOrganisationID, 
      ID(startNode(orgRel))as startNodeId, type(orgRel)as orgRel, ID(endNode(orgRel))as endNodeId, 
      ID(relatedOrganisation)as relatedOrganisationId, relatedOrganisation.name as relatedOrganisationName 
      COLLECT({ 
      queryPerson:{endpoint:{ID:ID(queryPerson)}, endpointrelationship: type(employmentRel)}, 
      relatedPerson:{endpoint:{ID:coalesce(ID(relatedPerson),ID(queryPerson))}, endpointrelationship:type(relatedOrgRel)} 
      }) as rels 

我本來期望所有收集到的結果是這樣的:

{ 
     "startEmp":{ 
     "ID":2715, 
     "startrelationship":"employee" 
     }, 
     "relatedEmp":{ 
     "ID":2722, 
     "endrelationship":"ex employee" 
     } 
    } 

但是直接連接的節點結果(同一節點ID)出現像:

{ 
     "startEmp":{ 
      "ID":2716, 
     "startrelationship":"employee" 
     }, 
     "relatedEmp":{ 
     "ID":2716, 
     "endrelationship":null 
     } 
    } 

這是爲什麼出現空類型(relatedOrgRel)?我誤解了OPTIONAL MATCH中發生了什麼,並且第二個OPTIONAL MATCH中的relatedOrgRel被null覆蓋了嗎?如果是這樣,我該如何補救?

謝謝

+0

你的Cypher有很多錯誤。你能展示一下你真正的Cypher,或者至少是合法的嗎? – cybersam

+0

這不是我的實際圖表 - 而是一個簡化版本(如果你能相信的話)。我更新了問題中的查詢,但無法運行。我正在尋求幫助,理解使用雙OPTIONAL MATCH時的概念/我的錯誤,而不是試圖讓這個例子密碼工作 – Airomega

回答

1

不,可選匹配不能覆蓋已定義的變量。

我覺得問題的原因是當你的第二個可選的匹配不會匹配任何東西,但是這是在你回來的人收集使用COALESCE部分掩蓋了隱藏一些conseque的:

... 
relatedPerson:{endpoint:{ID:coalesce(ID(relatedPerson),ID(queryPerson))}, endpointrelationship:type(relatedOrgRel)} 
... 

如果relatedPerson爲空,彷彿你的第二個可選的匹配失敗,那麼你就回落到queryPerson的ID將是,但因爲你不使用聚結relatedOrgRel,這將仍然是空的。在這裏你需要一個COALESCE,否則你需要找出一個更好的方法來處理你的OPTIONAL MATCHES中的null變量,以防失敗。

+0

我認爲你是現貨。我做了一個錯誤的假設,即第二個可選比賽正在返回,但這是工作中的聯合。謝謝 – Airomega