Zadałem pytanie earlier o agregowanie ilości wzdłuż wykresu. Dwie podane odpowiedzi działały dobrze, ale teraz próbuję rozszerzyć zapytanie Cyphera do wykresu o zmiennej głębokości.Zapytanie rekurencyjne z agregacją podageksową (dowolna głębokość)
Podsumowując, zaczynamy od kilku magazynów liści, z których wszystkie są powiązane z konkretnym dostawcą, który jest własnością węzła Store
. Zapasy są następnie przenoszone do innych sklepów, a udział poszczególnych dostawców odpowiada ich udziałowi w pierwotnym sklepie.
Więc dla węzła B02
, S2
przyczyniły 750/1250 = 60%
i S3
przyczyniły 40%
. Przesuwamy następnie 600 jednostek naszych z B02
, z których 60%
należy do S2
i 40%
do S3
i tak dalej.
Co chcemy wiedzieć, jaki procent końcowych 700 jednostek w D01
należeć do każdego dostawcy. Gdzie dostawcy o tej samej nazwie są tym samym dostawcą. Tak na powyższym wykresie oczekujemy:
S1, S2 38,09
, 27.61
S3 34,28
Mam przygotował wykres za pomocą tego skryptu Cypher:
CREATE (A01:Store {Name: 'A01', Supplier: 'S1'})
CREATE (A02:Store {Name: 'A02', Supplier: 'S1'})
CREATE (A03:Store {Name: 'A03', Supplier: 'S2'})
CREATE (A04:Store {Name: 'A04', Supplier: 'S3'})
CREATE (A05:Store {Name: 'A05', Supplier: 'S1'})
CREATE (A06:Store {Name: 'A06', Supplier: 'S1'})
CREATE (A07:Store {Name: 'A07', Supplier: 'S2'})
CREATE (A08:Store {Name: 'A08', Supplier: 'S3'})
CREATE (B01:Store {Name: 'B01'})
CREATE (B02:Store {Name: 'B02'})
CREATE (B03:Store {Name: 'B03'})
CREATE (B04:Store {Name: 'B04'})
CREATE (C01:Store {Name: 'C01'})
CREATE (C02:Store {Name: 'C02'})
CREATE (D01:Store {Name: 'D01'})
CREATE (A01)-[:MOVE_TO {Quantity: 750}]->(B01)
CREATE (A02)-[:MOVE_TO {Quantity: 500}]->(B01)
CREATE (A03)-[:MOVE_TO {Quantity: 750}]->(B02)
CREATE (A04)-[:MOVE_TO {Quantity: 500}]->(B02)
CREATE (A05)-[:MOVE_TO {Quantity: 100}]->(B03)
CREATE (A06)-[:MOVE_TO {Quantity: 200}]->(B03)
CREATE (A07)-[:MOVE_TO {Quantity: 50}]->(B04)
CREATE (A08)-[:MOVE_TO {Quantity: 450}]->(B04)
CREATE (B01)-[:MOVE_TO {Quantity: 400}]->(C01)
CREATE (B02)-[:MOVE_TO {Quantity: 600}]->(C01)
CREATE (B03)-[:MOVE_TO {Quantity: 100}]->(C02)
CREATE (B04)-[:MOVE_TO {Quantity: 200}]->(C02)
CREATE (C01)-[:MOVE_TO {Quantity: 500}]->(D01)
CREATE (C02)-[:MOVE_TO {Quantity: 200}]->(D01)
Obecne zapytanie to:
MATCH (s:Store { Name:'D01' })
MATCH (s)<-[t:MOVE_TO]-()<-[r:MOVE_TO]-(supp)
WITH t.Quantity as total, collect(r) as movements
WITH total, movements, reduce(totalSupplier = 0, r IN movements | totalSupplier + r.Quantity) as supCount
UNWIND movements as movement
RETURN startNode(movement).Supplier as Supplier, round(100.0*movement.Quantity/supCount) as pct
Próbuję użyć rekurencyjnych relacje, coś na wzór tego:
MATCH (s)<-[t:MOVE_TO]-()<-[r:MOVE_TO*]-(supp)
jednak, że daje wiele ścieżek do węzła końcowego i muszę agregować inwentaryzacji w każdym węźle myślę.
myślę o tym, choć problemem jest to, że nie sądzę, Cypher naprawdę rekursji. Cypher ocenia jeden subgraph na raz za pomocą 'MATCH', który w tym przypadku jest jedną ścieżką w głąb drzewa. Ale chcesz porównać ścieżki ze sobą –
Także, jeśli chcesz tylko ścieżek ze sklepu do oryginalnych węzłów dostawców, chcesz coś jak 'MATCH (cel: Store {Nazwa: 'D01'}) <- [ r: MOVE_TO *] - (źródło: Store) WHERE source.Supplier IS NOT NULL' –
Oprócz sugestii Briana, podobnie możesz użyć "WHERE NOT (source) <- [: MOVE_TO] -()' – JohnMark13