準備圖表用於迭代查詢(初始化臨時pcts
陣列,用於所有的起始Store
節點)。這包括創建一個具有包含所有供應商名稱的數組的單節點Suppliers
節點。這用於建立臨時pcts
數組元素的順序,並將這些元素映射回正確的供應商名稱。
MATCH (store:Store)
WHERE HAS (store.Supplier)
WITH COLLECT(store) AS stores, COLLECT(DISTINCT store.Supplier) AS csup
CREATE (sups:Suppliers { names: csup })
WITH stores, sups
UNWIND stores AS store
SET store.pcts =
EXTRACT(i IN RANGE(0,LENGTH(sups.names)-1,1) |
CASE WHEN store.Supplier = sups.names[i] THEN 1.0 ELSE 0.0 END)
RETURN store.Name, store.Supplier, store.pcts;
這裏是問題的數據結果:
+---------------------------------------------+
| store.Name | store.Supplier | store.pcts |
+---------------------------------------------+
| "A01" | "S1" | [1.0,0.0,0.0] |
| "A02" | "S1" | [1.0,0.0,0.0] |
| "A03" | "S2" | [0.0,1.0,0.0] |
| "A04" | "S3" | [0.0,0.0,1.0] |
| "A05" | "S1" | [1.0,0.0,0.0] |
| "A06" | "S1" | [1.0,0.0,0.0] |
| "A07" | "S2" | [0.0,1.0,0.0] |
| "A08" | "S3" | [0.0,0.0,1.0] |
+---------------------------------------------+
8 rows
83 ms
Nodes created: 1
Properties set: 9
迭代查詢(反覆運行,直到返回0行)
MATCH p=(s1:Store)-[m:MOVE_TO]->(s2:Store)
WHERE HAS(s1.pcts) AND NOT HAS(s2.pcts)
SET s2.pcts = EXTRACT(i IN RANGE(1,LENGTH(s1.pcts),1) | 0)
WITH s2, COLLECT(p) AS ps
WITH s2, ps, REDUCE(s=0, p IN ps | s + HEAD(RELATIONSHIPS(p)).Quantity) AS total
FOREACH(p IN ps |
SET HEAD(RELATIONSHIPS(p)).pcts = EXTRACT(parentPct IN HEAD(NODES(p)).pcts | parentPct * HEAD(RELATIONSHIPS(p)).Quantity/total)
)
FOREACH(p IN ps |
SET s2.pcts = EXTRACT(i IN RANGE(0,LENGTH(s2.pcts)-1,1) | s2.pcts[i] + HEAD(RELATIONSHIPS(p)).pcts[i])
)
RETURN s2.Name, s2.pcts, total, EXTRACT(p IN ps | HEAD(RELATIONSHIPS(p)).pcts) AS rel_pcts;
迭代1的結果:
+-----------------------------------------------------------------------------------------------+
| s2.Name | s2.pcts | total | rel_pcts |
+-----------------------------------------------------------------------------------------------+
| "B04" | [0.0,0.1,0.9] | 500 | [[0.0,0.1,0.0],[0.0,0.0,0.9]] |
| "B01" | [1.0,0.0,0.0] | 1250 | [[0.6,0.0,0.0],[0.4,0.0,0.0]] |
| "B03" | [1.0,0.0,0.0] | 300 | [[0.3333333333333333,0.0,0.0],[0.6666666666666666,0.0,0.0]] |
| "B02" | [0.0,0.6,0.4] | 1250 | [[0.0,0.6,0.0],[0.0,0.0,0.4]] |
+-----------------------------------------------------------------------------------------------+
4 rows
288 ms
Properties set: 24
迭代2結果:
+-------------------------------------------------------------------------------------------------------------------------------+
| s2.Name | s2.pcts | total | rel_pcts |
+-------------------------------------------------------------------------------------------------------------------------------+
| "C02" | [0.3333333333333333,0.06666666666666667,0.6] | 300 | [[0.3333333333333333,0.0,0.0],[0.0,0.06666666666666667,0.6]] |
| "C01" | [0.4,0.36,0.24] | 1000 | [[0.4,0.0,0.0],[0.0,0.36,0.24]] |
+-------------------------------------------------------------------------------------------------------------------------------+
2 rows
193 ms
Properties set: 12
迭代3結果:
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| s2.Name | s2.pcts | total | rel_pcts |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| "D01" | [0.38095238095238093,0.27619047619047615,0.34285714285714286] | 700 | [[0.2857142857142857,0.2571428571428571,0.17142857142857143],[0.09523809523809522,0.01904761904761905,0.17142857142857143]] |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row
40 ms
Properties set: 6
迭代4結果:
+--------------------------------------+
| s2.Name | s2.pcts | total | rel_pcts |
+--------------------------------------+
+--------------------------------------+
0 rows
69 ms
列表非零Supplier
百分比結束Store
(多個)節點。
MATCH (store:Store), (sups:Suppliers)
WHERE NOT (store:Store)-[:MOVE_TO]->(:Store) AND HAS(store.pcts)
RETURN store.Name, [i IN RANGE(0,LENGTH(sups.names)-1,1) WHERE store.pcts[i] > 0 | {supplier: sups.names[i], pct: store.pcts[i] * 100}] AS pcts;
結果:
+----------------------------------------------------------------------------------------------------------------------------------+
| store.Name | pcts |
+----------------------------------------------------------------------------------------------------------------------------------+
| "D01" | [{supplier=S1, pct=38.095238095238095},{supplier=S2, pct=27.619047619047617},{supplier=S3, pct=34.285714285714285}] |
+----------------------------------------------------------------------------------------------------------------------------------+
1 row
293 ms
我想這一點,但問題是,我不認爲CYPHER確實遞歸。 Cypher每次評估一個子圖時使用它的「MATCH」,在這種情況下,它是跨越樹深度的一條路徑。但是,您想比較彼此的路徑 – 2015-01-21 08:57:44
另外,如果您只想從商店到原始供應商節點的路徑,您希望像'MATCH(target:Store {Name:'D01'})< - [ r:MOVE_TO *] - (source:Store)WHERE source.Supplier IS NOT NULL' – 2015-01-21 08:58:54
除了Brians的建議,同樣可以使用WHERE NOT(source)< - [:MOVE_TO] - ()' – JohnMark13 2015-01-23 10:45:43