2016-05-15 14 views
0

収束してから再び発散する複数の経路上の集約に関する質問があります。集約の中には、パスのサブセットのみを考慮する必要がありますが、集約の一部は考慮する必要があります。Cypher発散と収束経路集約

これは、製品製造の例を使用して、私がこれを最もよく説明します。 私は1つの製品を生産しているサプライヤーから供給されたいくつかの材料からなる会社を持っているとしましょう。 具体的には、この会社は10グラムの材料からなる1つの製品タイプの5つのアイテムを生産しています。したがって、製造プロセス中に材料の50グラムを使用しました。しかし、生産には廃棄物があり、実際には70グラムを使い、20を無駄にしました。

私が計算したいのは、廃棄物を考慮して製品とサプライヤごとの材料の補正重量です。この場合、簡単です。何が起こる70グラム

simple production

が、これはより複雑になった場合:complex production

今すぐ製品1とsupplier1あたりmaterial1に対する補正重量は58.82グラムです。 これは式である:

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

すなわち

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

すなわち製品、材料、サプライヤの順列の数であるように、この例の上CYPHERクエリを実行すると、私は6件の結果を与えるべきです。

質問は、そのようなクエリを書く方法です。

を作成します:

だけで完全なものにするため、ここではグラフを生成するCYPHERだ...私はなどの、と繰り返し機能を軽減しようとしましたが、常に、ノードの間違ったセットを超える集約するようだ

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) 

答えて

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! ほぼ正しいですが、私は最初から苦労した問題は1つだけです。 mCompの合計はサプライヤーの経路にも計算されています。ですから、material2は1750ではなく3500になります。 何とか私はサプライヤーパスが計算される前にマテリアルパスを取得できる必要があります。しかし、2度のマッチングはとにかく追加のパスにつながります... – superkruger

+0

MATCH(C:Company {id: 'c1'}) < - [pb:PRODUCED_BY] - (P:製品) - [コ:CONSISTS_OF] - > (M:材質) - [PF:PURCHASED_FROM] - > (S:サプライヤー) M、 SUM(pb.amount * co.amount)MCOMP、 としてWITH(収集{ 製品:P.name、製品名:pb.amount、comp:co.amount、購入:pf.amount、サプライヤ:S.name })as tmps UNWIND tmps as tmp RETURN tmp ['product'] as製品名、材料としてのM.name、サプライヤとしてのtmp ['supplier']、mComp、1。0 * tmp ['prod'] * tmp ['comp'] * tmp ['購入']/mComp as cWeight – superkruger

+0

SUMがないと、製品に基づいて個々のマテリアル構成が得られます。しかし、SUMの場合は、サプライヤーの合計も合計: MATCH(C:Company {id: 'c1'})< - [pb:PRODUCED_BY] - (P:製品) - [co:CONSISTS_OF] - > )、 - (pf:PURCHASED_FROM) - >(S:サプライヤー)m(pb.amount * co.amount)とmCompは、(product:P.name、prod:pb.amount、comp:co.amount、サプライヤーとしてのtmp ['supplier']、mComp、1.0 * tmp ['product']製品として、製品名としてMname、tmpとしてUNWIND tmps tmp [ 'プロンプト'] * tmp ['comp'] * tmp ['購入']/mComp as cWeight – superkruger