2016-05-15 5 views
0

Ich habe eine Frage in Bezug auf Aggregate über mehrere Pfade, die konvergiert und dann wieder divergiert. Einige der Aggregate sollten dann nur eine Teilmenge der Pfade berücksichtigen, andere mehr.Cypher divergierende und konvergierende Pfad Aggregat

Ich werde dies so gut wie möglich anhand eines Beispiels der Produktherstellung erklären. Angenommen, ich habe ein Unternehmen, das 1 Produkt produziert, das aus einem Material besteht, das von einem Lieferanten geliefert wird. Um genauer zu sein, produziert dieses Unternehmen 5 Artikel eines Produkttyps, bestehend aus 10 Gramm eines Materials. Deshalb haben sie während des Herstellungsprozesses 50 Gramm des Materials verwendet. Aber in der Produktion gibt es Materialverschwendung, und sie haben tatsächlich 70 Gramm verwendet und 20 verschwendet.

Was ich gerne berechnen würde, ist das korrigierte Gewicht des Materials pro Produkt und Lieferanten unter Berücksichtigung der Verschwendung. In diesem Fall ist es einfach.

70g

simple production

Was passiert, wenn dies wird immer komplexer: complex production

nun das korrigierte Gewicht für material1 pro product1 und supplier1 58,82 Gramm. Dies ist die Formel:

material composition = sum(production amount * product composition) 
corrected weight = (production amount * product composition * 
        (purchased/(material composition))) 

heißt

material composition = (5 * 10) + (20 * 40) = 850 
corrected weight = (5 * 10 * (1000/(850))) = 58.82 

So sollte 6 Ergebnisse geben Sie mir eine Chiffre-Abfrage in diesem Beispiel ausgeführt wird, als dass die Anzahl der Permutationen von Produkten, Materialien und Lieferanten ist.

Frage ist, wie man eine solche Abfrage schreibt. Ich habe versucht, Funktionen zu reduzieren, mit wiederholten, etc, aber es scheint immer die falsche Menge von Knoten zu aggregieren über ...

Nur der Vollständigkeit halber, hier ist die Chiffre um die Grafik zu erzeugen:

erstellen:

create (c:Company {name:'test', id:'c1'}), 
     (p1:Product {name:'product1', id:'p1'}), 
     (p2:Product {name:'product2', id:'p2'}), 
     (m1:Material {name:'material1', id:'m1'}), 
     (m2:Material {name:'material2', id:'m2'}), 
     (s1:Supplier {name:'supplier1', id:'s1'}), 
     (s2:Supplier {name:'supplier2', id:'s2'}), 
     (s3:Supplier {name:'supplier3', id:'s3'}) 

Rels:

match (c:Company {id:'c1'}), 
    (p1:Product {id:'p1'}), 
    (m1:Material {id:'m1'}) 
    merge (c)<-[pb_r1:PRODUCED_BY {amount:5}]-(p1)-[co_r11:CONSISTS_OF {amount:10}]->(m1) 
    with c, p1, m1 
    match (p2:Product {id:'p2'}) 
    merge (c)<-[pb_r2:PRODUCED_BY {amount:20}]-(p2)-[co_r12:CONSISTS_OF {amount:40}]->(m1) 
    with p1, p2, m1 
    match (s1:Supplier {id:'s1'}) 
    merge (m1)-[pf_r1:PURCHASED_FROM {amount: 1000}]->(s1) 
    with p1, p2 
    match (m2:Material {id:'m2'}) 
    merge (p1)-[co_r21:CONSISTS_OF {amount:30}]->(m2) 
    with p2, m2 
    merge (p2)-[co_r22:CONSISTS_OF {amount:80}]->(m2) 
    with m2 
    match (s2:Supplier {id:'s2'}) 
    merge (m2)-[pf_r2:PURCHASED_FROM {amount: 1000}]->(s2) 
    with m2 
    match (s3:Supplier {id:'s3'}) 
    merge (m2)-[pf_r3:PURCHASED_FROM {amount: 1000}]->(s3) 

Antwort

1
// Selection of the supply chain and production by Company 
// 
MATCH (C:Company {id:'c1'}) 
     <-[pb:PRODUCED_BY]- 
     (P:Product) 
     -[co:CONSISTS_OF]-> 
     (M:Material) 
     -[pf:PURCHASED_FROM]-> 
     (S:Supplier) 

// Grouping by materials, calculation material composition, 
// and the preservation of the chain to the supplier 
// 
WITH M, 
    S, // group by supplier 
    SUM(pb.amount*co.amount) as mComp, 
    collect({ 
     product:P, 
     prod: pb.amount, 
     comp: co.amount, 
     purchased: pf.amount 
    }) as tmps 

// Calculating the correct weight by material and supplier 
// 
UNWIND tmps as tmp 
RETURN M as material, 
     tmp['product'] as product, 
     S as supplier, 
     1.0 * tmp['prod'] * tmp['comp'] * tmp['purchased']/mComp as cWeight 
+0

+1 für das schnelle Ergebnis! Fast richtig, es gibt immer noch ein Problem, mit dem ich von Anfang an zu kämpfen hatte. Die mComp-Summe wird auch über Lieferantenwege berechnet. Also, wir bekommen 3500 statt 1750 für Material2. Irgendwie muss ich in der Lage sein, Materialpfade zu bekommen, bevor Lieferantenwege berechnet werden. Aber die doppelte Übereinstimmung würde sowieso zu zusätzlichen Pfaden führen ... – superkruger

+0

Führen Sie das aus, um zu sehen, was ich meine: MATCH (C: Company {id: 'c1'}) <- [pb: PRODUCED_BY] - (P: Produkt) - [co: consists_of] -> (M: Material) - [pf: PURCHASED_FROM] -> (S: Lieferant) MIT M, SUM (pb.amount * co.amount) als MCOMP, sammeln ({ Produkt: P.name, prod: pb.amount, comp: co.amount, gekauft: pf.amount, Lieferant: S.name }) als tmps UNWIND tmps als tmp RETURN tmp ['product'] as Produkt, M.name als Material, tmp ['Lieferant'] als Lieferant, mComp, 1.0 * tmp ['prod'] * tmp ['comp'] * tmp ['gekauft']/mComp als cWeight – superkruger

+0

Ohne die SUM, gibt es individuelle Materialzusammensetzungen basierend auf Produkten. Aber mit der SUM, es summiert sich auch über Lieferanten: MATCH (C: Firma {id: 'c1'}) <- [pb: PRODUZIERTE_BY] - (P: Produkt) - [co: CONSISTS_OF] -> (M: Material) - [pf: PURCHASED_FROM] -> (S: Lieferant) WITH M, (pb.amount * co.amount) als mComp, collect ({Produkt: P.name, prod: pb.amount, comp: co.amount, gekauft: pf.menge, Lieferant: S.name}) als tmps UNWIND tmps als tmp RETURN tmp ['Produkt'] als Produkt, M.name als Material, tmp ['Lieferant'] als Lieferant, mComp, 1.0 * tmp [ 'prod'] * tmp ['comp'] * tmp ['gekauft']/mComp als cWeight – superkruger