2016-12-01 44 views
2

讓我們考慮一個簡單的例子,有兩種類型的節點:公司和工人。對於任何一對公司c1和c2(我尊重一些我將忽略的條件),我需要知道:1.他們有多少共同工人,有多少工人有c1,有多少工人有c2。Neo4j Cypher路徑使用幾次相同的邊

我的第一個猜測是:

MATCH (w_c1:Worker)--(c1:Company)--(w_common)--(c2:Company)--(w_c2:Worker) 
WHERE <something> 
RETURN c1, c2, COUNT(DISTINCT w_common), COUNT(DISTINCT w_c1), COUNT(DISTINCT w_c1) 

這一要求的問題是,如果我有任何對連接的節點,COUNT(DISTINCT w_c1)(ID爲w_c2)之間只有一個鏈接就只算c1中不屬於c2的工作人員。但是如果我在一些節點之間有幾個關係,結果有時候是「正確的」。這聽起來像比賽中的路徑不會「回來」:(w_common) - (c2:公司) - (w_c2:工人)將不匹配(「worker1」) - (「company2」) - ( 「worker1」)(這可能有助於避免無限循環)。

我的第二個猜測是兩個部分分割的要求: 我的第一個猜測是:

MATCH (c1:Company)--(w_common)--(c2:Company) 
MATCH (c1)--(w_c1:Worker), (c2)--(w_c2:Worker) 
WHERE <something> 
RETURN c1, c2, COUNT(DISTINCT w_common), COUNT(DISTINCT w_c1), COUNT(DISTINCT w_c1) 

不過,結果是正確的,但我有一個關於笛卡爾積的警告,而事實上,在大數據集,我的請求不會在數小時後完成。我在兩場比賽之間嘗試了「WITH c1,w_common,c2」,但我仍然有警告

我該如何繼續?

回答

1

有一件事會幫助你的是SIZE()函數,它可以告訴你一個模式的出現次數,例如:Worker per:Company。

這種查詢可以爲你工作,假設一個工人對公司的工作只有一個關係到公司:

MATCH (c1:Company)--(w_common:Worker)--(c2:Company) 
WHERE <your criteria for matching on a specific c1 and c2> 
RETURN COUNT(w_common) as inCommonCount, SIZE((c1)--(:Worker)) as c1Count, SIZE((c2)--(:Worker)) as c2Count 
+0

謝謝,我確實嘗試了SIZE函數,但是我可能在給定的公司和工人之間有幾個關係(例如對應於幾個工作階段)。 – Vandy

+1

您是否有特定的「:HIRED」,每個工人只能出現一次?然後你可以做一些像'size((c1) - [:HIRED] - >())'。 –

1

您可以使用小計:

OPTIONAL MATCH (C1:Company {name: 'c1'}) 
OPTIONAL MATCH (C2:Company {name: 'c2'}) 
WITH C1, C2 
MATCH (C:Company)<-[:workto]-(W:Worker) WHERE C = C1 OR C = C2 
WITH C1, C2, W, 
    sum(CASE WHEN C = C1 THEN 1 ELSE 0 END) as tmp1, 
    sum(CASE WHEN C = C2 THEN 1 ELSE 0 END) as tmp2 
RETURN C1, C2, 
     sum(tmp1) as cc1, sum(tmp2) as cc2, 
     sum(tmp1 * tmp2) as common 
相關問題