2017-08-12 64 views
0

以下是我的Neo4j DB模型的簡化模式。 我嘗試了幾個基於一些帖子的Cypher查詢,但沒有任何工作。我需要Neo4j查詢幫助

My Neo4j Model Example

我想找到所有的部件和所有的供應商,爲自行車數量。

複雜性在於某些組件與供應商相關聯,在這種情況下,只有在上層組件具有正確版本時纔會遵循分支。

實例:

  • 自行車數6具有分量ID = 3與供應商ID = 3和組件ID = 1與供應商ID = 1
  • 自行車數1具有部件ID = 1與供應商ID = 2
  • 自行車數3具有成分ID = 1與供應商ID = 2,部件ID = 2與供應商ID = 3

我想獲得的節點和的關係。

有人可以幫助我嗎?

+2

那麼每個自行車有一個節點,給它一個數字。 (b:自行車) - [:COMPOSED_OF] - >(c:Component {reference:internalRefAtBi​​keMaker}) - [:SUPPLIED_BY {supplierPartReference:azertyui}] - >(s:Supplier {name:「SuperSupplier」}) 類似的東西 –

+0

我會知道如何查詢這樣的圖表,如果我可以創建它:)。但我不知道如何重組整個圖,因爲它由1百萬個可能的組件組成。如果你可以幫助我創建圖表,你可以從我發佈的圖表中提出,它可能是一個解決方案... – lug

+0

看起來你對同一供應商使用多個節點,因爲圖形中的供應商節點確實象徵着供應商的一部分,而不是自己的供應商。這在你的'(:Supplier) - [:IsIn] - >(:Component)'關係中也很明顯,因爲它通常沒有意義,除非節點是特定部件的供應商。說'(:Component) - [:IsIn] - >(:Component)''會更有意義。你有沒有靈活性來修復這個數據模型?由於它存在,您也無法利用索引查找,因此在大圖上查詢速度會很慢。 – InverseFalcon

回答

0

基本上,你想要的是把所有子圖的項目,但過濾掉失敗的過濾器關係的路徑。您可以使用ALL/NONE/ANY來確保拾取的路徑不違反任何約束。

下面是一個假設from和to可以單獨定義的例子,但我認爲它足夠清晰以適應您的需求。(注意:您可以使用TYPE(r)檢查關係類型名稱太)

WITH 11 as num 
MATCH p=(s:Bike)-[*..25]-(n) 
WHERE 
ALL(r IN RELATIONSHIPS(p) WHERE 
    (NOT EXISTS(r.RANGEFROM) OR toInteger(r.RANGEFROM) <= num) AND 
    (NOT EXISTS(r.RANGETO) OR num <= toInteger(r.RANGETO))) 
AND TYPE(RELATIONSHIPS(p)[-1]) = "LO" 
WITH NODES(p) as ns, RELATIONSHIPS(p) as rs 
UNWIND ns as n UNWIND rs as r 
RETURN COLLECT(DISTINCT n), COLLECT(DISTINCT r) 

或者這應該是更有效的。

WITH 11 as num 
MATCH (ci)-[lo:LO]->(ds) 
WHERE toInteger(lo.RANGEFROM) <= num <= toInteger(lo.RANGETO) 
WITH ds, COLLECT(lo) as lo 
MATCH p=shortestpath((b:Bike)-[*..25]->(ds)) 
WHERE ALL(r IN RELATIONSHIPS(p) WHERE TYPE(r) <> "LO" OR r in lo) 
WITH NODES(p) as ns, RELATIONSHIPS(p) as rs 
UNWIND ns as n UNWIND rs as r 
RETURN COLLECT(DISTINCT n), COLLECT(DISTINCT r) 

注意:如果你需要更好的性能,你可能要考慮使用的Neo4j Traversal API

+0

此查詢不考慮組件是否具有來自供應商的「Isin」關係,它不回答我的需求:( – lug

+0

@lug「IsIn」如何影響結果?問題(如當前寫入十)只關心一個未命名的關係中的「FROMBIKE」和「TOBIKE」。由於「IsIn」沒有這些屬性中的任何一個,所以這個查詢應該很好地遍歷它。 (基本上,如果該屬性已定義,它只檢查關係的一部分,否則默認爲true) – Tezra

+0

好的。我明白。當我運行查詢時,我只檢索Bike節點和第一級組件。我需要將Bike + Components + Supplier + Components鏈接到供應商(如果存在),並且如果FROM和TO在搜索範圍內...... – lug

3

這是一個簡單的數據模型。除了Bike,ComponentSupplier節點標籤之外,該型號還添加了一個Part節點標籤。

(b:Bike)-[HAS_COMPONENT]->(c:Component)-[:IS_PART]->(p:Part) 
(c)-[:SUPPLIED_BY]->(s:Supplier) 

在該模型:

  • Part是由特定製造商生產的特定項目,並且它可以通過任何數量的Supplier s內出售。
  • A Bike由多個Component組成,其中每個是從特定Supplier購買的Part

在這種模式下,這裏是一個簡單的查詢返回,特定的自行車,每個組成部分,它的供應商:

MATCH 
    (:Bike {id: 1})-[HAS_COMPONENT]->(c)-[:IS_PART]->(part), 
    (c)-[:SUPPLIED_BY]->(supplier) 
RETURN part, supplier; 
+0

謝謝你的例子。不幸的是,它並沒有幫助我。自行車的「有效性」不是自行車的屬性,而是關係。我無法更改數據模型;它被強加給我。 – lug

1

不知道如果我理解正確的,但將這項工作?

MATCH p=(b:Bike {bnumber = 6})-[hc:HAS_COMPONENT]-(c:Component)-[hs:HAS_SUPPLIER]-(s:Supplier) 
WHERE hs.frombike >= bnumber 
    AND hs.tobike <= bnumber 
RETURN p; 

我同意@cybersam,你可以做一個簡化的模型。提出這個問題。

希望這會有所幫助。

問候, 湯姆

+0

我很驚訝這兩個建議認爲,自行車號碼是自行車的屬性,而不是關係的屬性。我認爲neo4j是解析產品結構和計算產品配置的正確數據庫。也許neo4j不如我的強大。與neo4j沒有辦法? – lug

+0

所以,啓發我們,你從哪裏得到自行車號碼?因爲它沒有在你的圖表中找到的地方。那麼假設它是什麼標識一輛自行車(並因此是自行車的屬性)是如此奇怪,並且來自自行車和自行車(一種關係的屬性,而不是屬性btw)表示這些相同數字的範圍?所以請解釋你如何走你的圖來獲得結果! –

+0

在圖中,自行車可以由3個組件組成:ID = 1,2和3. 每個組件都由供應商引以爲豪。 要知道哪個組件是由什麼組成的,以及誰爲每個自行車編號提供的,自行車編號的範圍由FROMBIKE和TOBIKE給出:FROMBIKE = 1表示從自行車編號1和TOBIKE = 5表示編號爲5的自行車。例如,自行車1只有組件1由供應商1提供。組件3僅用於自行車4(FROMBIKE = 4,TOBIKE = 20)。 問題是組件2.它的範圍從3到5,但它與供應商1相關聯。我必須考慮組件1的範圍及其範圍, – lug