Prepare a graph for an iterative query (initializes a temporary pcts array for all starting Store nodes). This includes creating a singleton Suppliers node, which has an array with all the names of the providers. This is used to determine the order of the elements of the pcts temporary arrays and to match these elements with the correct provider name.
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;
Here is the result with the question data:
+---------------------------------------------+ | 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
Iterative query (repeated until 0 rows are returned)
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;
Result Iteration 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
Result of iteration 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
Result of iteration 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
Result of iteration 4:
+--------------------------------------+ | s2.Name | s2.pcts | total | rel_pcts | +--------------------------------------+ +--------------------------------------+ 0 rows 69 ms
List non-zero Supplier percentages to end with Store node (s).
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;
Result:
+----------------------------------------------------------------------------------------------------------------------------------+ | store.Name | pcts | +----------------------------------------------------------------------------------------------------------------------------------+ | "D01" | [{supplier=S1, pct=38.095238095238095},{supplier=S2, pct=27.619047619047617},{supplier=S3, pct=34.285714285714285}] | +----------------------------------------------------------------------------------------------------------------------------------+ 1 row 293 ms