2017-02-01 74 views
1

在我的Neo4j /春數據Neo4j的4項目,我有一個實體:ProductNeo4j的暗號查詢基於特徵尋找節點三角洲

Product有一個Integer屬性 - price

,比如我有一個下產品價格:

Product1.price = 100 
Product2.price = 305 
Product3.price = 10000 
Product4.price = 1000 
Product5.price = 220 

產品之間沒有相互關聯的關係。

我需要根據初始價格值(Cypher查詢參數)查找一個由最大價格增量(Cypher查詢參數)相互區分的產品集合(路徑)。

比如我需要找到所有產品的Neo4j數據庫從價格開始= 50和價格三角洲= 150作爲輸出我希望得到以下產品:

Product1.price = 100 
Product5.price = 220 
Product2.price = 305 

的計算是這樣的:

起點價格= 50,所以第一個產品的價格應該不低於50,不超過200(50 + 150)。基於此,我們從目錄中找到了一個產品,價格= 100.第二個產品的價格應該不低於100,不超過250(100 + 150)..這是一個價格= 220的產品..第三個價格不低於220,不超過370.這是一個價格= 305的產品

請問您能展示一個Cypher查詢,它可以找到這樣的產品。

+0

您能否澄清如何將價格和價格增量因素納入您的計算?我的假設是,你想從價格開始,三角洲會給你一個價格上限和/或三角洲,但這意味着上限將是200(50 + 150)。您的輸出中的價格超過了這個水平,所以我的假設是錯誤的,但我不知道您想要使用什麼計算。 – InverseFalcon

+0

這樣的事情? WITH 50 AS initPrice,150 AS增量 WITH \t CASE \t WHEN(initPrice-Δ)> 0 THEN(initPrice-Δ) ELSE 0 END AS lowRange, (initPrice +增量)AS高變速 MATCH(正:Product) WHERE lowRange logisima

+0

這似乎與我的假設相符,但是您的示例輸出中的價格值不符合該公式(220和305的價格都高於計算極限200)。如果這只是您的示例輸出中的問題,是否可以修復它以避免混淆? – InverseFalcon

回答

1

作爲一個替代的解決方案應該是更快的查詢,但需要更多的維護和保養,以保持(尤其是快速變化的產品正常工作價格數據),您可以按照升序價格順序在產品節點之間創建關係,並將增量值保留爲關係屬性。

這裏是你如何可以創建這個使用APOC程序:

MATCH (p:Product) 
WITH p 
ORDER BY p.price ASC 
WITH apoc.coll.pairsMin(COLLECT(p)) as products 
UNWIND products as prodPairs 
WITH prodPairs[0] as prod1, prodPairs[1] as prod2 
CREATE (prod1)-[r:NextProd]->(prod2) 
SET r.delta = prod2.price - prod1.price 

而這裏的,一旦它的成立可以如何查詢此。

WITH {startPrice:50, delta:150} as params 
WITH params, params.startPrice + params.delta as ceiling 
MATCH (start:Product) 
WHERE params.startPrice <= start.price <= ceiling 
WITH start, params 
ORDER BY start.price ASC 
LIMIT 1 
MATCH (start)-[r:NextProd*0..]->(product:Product) 
WHERE ALL(rel in r WHERE rel.delta <= params.delta) 
RETURN DISTINCT product 

這應該是相當快的查詢,如當它到達超過所希望的增量的關係的ALL()謂詞應切斷可變匹配。

當然,缺點是您需要確保影響鏈接列表結構的每項操作(添加或刪除產品以及更改產品價格)適當調整結構,並且您可能需要考慮鎖定確保線程安全的方法,以便在產品和/或價格同時更新時不會破壞鏈表。

+0

謝謝!看起來這是現在最好的方式 – alexanoid

+0

這種方法的主要問題是,我無法跳過此列表中的某些產品,或者甚至根據查詢中的不同條件遍歷不同的路徑。例如,如果我' d喜歡在價格中添加一些附加條件..就像WHERE product.color ='red'那麼這種方法看起來像不起作用 – alexanoid

+0

您將無法跳過產品,但可以添加其他條件,包括on節點本身。在ALL()函數中,最後加上:AND endNode(rel).color ='red''。這將增加額外的要求,即路徑中的所有產品都必須是紅色的。 – InverseFalcon

1

這在Cypher中執行起來相當複雜。唯一的方法是使用REDUCE()函數和CASE語句,如果產品在列表中最後一個產品的價格的增量範圍內,則有條件地將產品添加到列表的末尾。

請記住,使用此方法無法將產品處理短路。如果總共有100萬種產品,並且我們在產品的有序列表中發現只有前兩種產品在該增量模式內,該查詢將繼續檢查剩下的一百萬種產品中的每一種,儘管它們中的任何一種都不會加入我們的清單。

此查詢應該適合您。

WITH {startPrice:50, delta:150} as params 
MATCH (p:Product) 
WHERE p.price >= params.startPrice 
WITH params, p 
ORDER BY p.price asc 
WITH params, COLLECT(p) as products 
WITH params, TAIL(products) as products, HEAD(products) as first 
WHERE first.price <= params.startPrice + params.delta 
WITH REDUCE(prods = [first], prod in products | 
    CASE WHEN prod.price <= LAST(prods).price + params.delta 
     THEN prods + prod 
     ELSE prods END) as products 
RETURN products 
+0

非常感謝!有什麼方法可以優化此架構,以便在查找產品時不影響性能。在產品目錄或其他內容中創建新產品時可能會添加某種關係?性能是這個系統的重要標準之一。 – alexanoid

+0

我能想到的使用該路線的唯一優化是按照價格從小到大的順序連接產品,並將每個關係的增量屬性設置爲所連接節點的價格之間的增量。這將使您可以使用ALL()執行有效的可變長度匹配,以確保路徑中的所有關係增量低於您的增量參數,但如果價格更改或產品定期移除或插入,則這將維護繁重。如果您想了解更多詳細信息,我可以將其添加爲單獨的答案。 – InverseFalcon

1

該解決方案需要在迭代過程中轉換中間結果。一個有趣的問題,因爲今天密碼不直接提供這種可能性。作爲一個練習(草圖)使用apoc.periodic.commit程序從APOC -library:

CALL apoc.create.uuid() YIELD uuid 
CALL apoc.periodic.commit(" 
    MERGE (H:tmpVars {id: {tmpId}}) 
    ON CREATE SET H.prices = [], 
       H.lastPrice = {lastPrice}, 
       H.delta = {delta} 
    WITH H 
    MATCH (P:Product) WHERE P.price > H.lastPrice AND 
          P.price < H.lastPrice + H.delta 
    WITH H, max(P.price) as lastPrice 
    SET H.lastPrice = lastPrice, 
     H.prices = H.prices + lastPrice 
    RETURN 1 
    ", {tmpId: uuid, delta: 150, lastPrice: 50} 
) YIELD updates, executions, runtime 
MATCH (T:tmpVars {id: uuid}) 
WITH T, T.prices as prices DETACH DELETE T 
WITH prices 
UNWIND prices as price 
MATCH (P:Product) WHERE P.price = price 
RETURN P ORDER BY P.price ASC 
+0

感謝您的回答!你能否從性能的角度評論這個意見?這個問題如何依賴於數據庫中的產品編號? – alexanoid

+0

@alexanoid對不起。這只是一個草圖,一個想法。沒有性能:) –