2014-03-27 14 views
1

我有一個包含許多地方的原始項目可以被克隆項目導致實施「貪婪」的比賽找到了樹的程度Cypher支架

(clone:Item)-[:clones]->(original:Item) 

和的「子樹」的圖表克隆項也可以被克隆:

(newclone:Item)-[:clones]->(clone:Item) 

中的第一項是由用戶創建的:

(:User)-[:created]->(:item) 

和克隆COL由用戶引用:

(:User)-[:collected]->(:item) 

鑑於樹中的任何項目,我希望能夠匹配樹中的所有項目。我使用的是:

(1) match (known:Item)-[:clones*]-(others:Item) 

我的理解是,這實現了「貪婪」的比賽,在各個方向遍歷樹,匹配的所有項目。

一般來說,這工作然而,在某些情況下,它似乎不匹配樹中的所有項目。例如,在下面的查詢中,這似乎不匹配整個子樹。

match p = (known:Item)-[r:clones*]-(others:Item) where not any(x in nodes(p) where (x)<-[:created]-(:User)) return p 

在這裏,我試圖找到它們缺少一個「創造」項目(這是在源SQL數據庫中刪除子樹。

什麼我發現是,它給我誤報的原因,它只匹配特定樹的一部分,例如,如果有一棵樹有5個項目按照上述方式正確構建,似乎(在某些情況下)匹配樹的一個子集(可能是5個項目中的2個)和該子集包含創建的卡,因此利用該查詢返回的時候我沒想到它。

問題 是我的邏輯正確,或我誤解的東西嗎?我懷疑我誤解了路徑,但我很困惑,因爲基本的「貪婪」匹配在大多數情況下都適用。

認爲我的問題是,我一直困惑,因爲查詢是在樹中發現多個路徑,其中一些滿足查詢中的測試,有些則不。在neo4j可視化中查看時,多條路徑被整合到整個樹中,而表格結果顯示上面的匹配(1)實際上給出了多條路徑。

我現在在想,我應該使用的集合,而不是該路徑。

+0

您的問題*顯示*有矛盾。您聲明:(1)「第一個項目是由用戶創建的」,(2)「整棵樹會通過測試」。但是,如果沒有節點由用戶創建,那麼您的測試只會傳遞給整個樹。所以,(1)和(2)不能同時成立。請更正您的問題陳述。 – cybersam

回答

1

你說得很對,查詢比什麼是瀏覽器的可視化明顯的匹配更路徑。該查詢是在這個意義上,它沒有上限深度貪心,但它也有沒有下限(井,嚴格下限爲1),這意味着它會發出一個短的路徑和包括它,如果較長的路徑有這樣的。對於像

CREATE 
(u)-[:CREATED]->(i)<-[:CLONES]-(c1)<-[:CLONES]-(c2) 

數據的查詢將匹配路徑

i<--c1 
i<--c1<--c2 
c1<--c2 
c2-->c1 
c2-->c1-->i 
c1-->i 

這些路徑中,只有含有i的那些將由條件NOT x<-[:CREATED]-()被過濾,留下路徑

c1<--c2 
c2-->c1 

您需要在該過濾器之前的模式中的進一步條件,使得每個通過它的路徑應爲包含一些節點x,其中x<-[:CREATED]-()。那樣的過濾條件是明確的。從您問題中的示例模型/數據來看,您可以嘗試匹配所有定向變量深度(clone)-[:CLONES]->(cloned)路徑,其中最後一個克隆本身並不克隆任何東西。最後克隆的應該是一個創建的項目,所以現在找到的每個路徑都可以包含一個b<-[:CREATED]-()。也就是說,如果創建的項目不克隆什麼,這樣的事情應該工作

MATCH (a)-[:CLONES*]->(b) 
WHERE NOT b-[:CLONES]->() 
    AND NOT b<-[:CREATED]-() 

這依賴於僅匹配路徑其中每個路徑的特定節點可以預期被創建。另一種方法是通過將單個指針放入樹中,並對整個樹測試任何已創建的項目節點,來自行處理每棵樹。然後,你的查詢的問題可以說是它將c1<--c2視爲一棵完整的樹,而他的解決方案是一個只爲樹匹配一次的模式。然後,您可以從那裏收集具有可變深度匹配的樹的節點。你可以用不同的方式得到這樣一個指針,最簡單的方法是提供一個區分屬性來查找特定節點並收集該節點樹中的所有項目。也許類似

MATCH (i {prop:"val"})-[:CLONES*]-(c) 
WITH i, collect(distinct c) as cc 
WHERE NOT (
    i<-[:CREATED]-() OR 
    ANY (c IN cc WHERE c<-[:CREATED]-() 
) //etc 

這不是一個普通的查詢,但是,因爲它只能在一個節點的一棵樹。如果您擁有每棵樹唯一的屬性模式,則可以使用該模式。您還可以建模數據,使每棵樹與包含「森林」的關係完全一致。

MATCH (forest)-[:TREE]->(tree)-->(item)-[:CLONES*]-(c) // etc 

如果您[:COLLECTED]或者有其他關係,或關係和屬性的結合,使每棵樹的獨特模式,這些也可以使用。