2017-07-31 17 views
1

私はcontains-関係で接続された私のデータベース内に注文や製品のノードを持つ:最も一般的なタプル

(:order)-[:contains]->(:product) 

最も一般的なのnタプルを見つけることが可能である場合、私は思ったんだけど同じ順序で発生する製品の

私は1500以上の製品を持っているので、これは可能ではないのですが、これらの可能な組み合わせの数は、たとえ小さなnの場合でも非常に高くなります。 1500×4≒5×10^12。私はnの次のテストクエリを書かれている

= 3:

MATCH (o:order)-[r:contains]->(p:product) 
WITH count(r) as NrProds, o 
MATCH (o)-[r:contains]->(p:product) 
WHERE NrProds > 3 
WITH o 
MATCH (o)-[r1:contains]->(p1:product),(o)-[r2:contains]->(p2:product),(o)-[r3:contains]->(p3:product) 
WITH o,p1,p2,p3,count(r1) as r1,count(r2) as r2,count(r3) as r3 
WITH o,p1,p2,p3, 
CASE WHEN r1<r2 AND r1<r3 THEN r1 
    WHEN r2<r1 AND r2<r3 THEN r2 
    WHEN r3<r1 AND r3<r2 THEN r3 
    END as result 
WITH result,o,p1,p2,p3 
RETURN count(result) as NrPurchs, o.Id,p1.name,p2.name,p3.name ORDER BY NrPurchs DESC 

まず私はその後、それらはすべての注文の巨大な一部を構成するよう未満3カウント、製品のいずれかの注文を考慮しないようにしてくださいこれらの注文の包含関係を照合します。 大きなジョインが作成されたため、私のコンピュータはクエリを終了しません。

私のコンピュータが計算を完了できるように、非常に多くの可能性を照会することを伴わないタプルを見つける方法はありますか?

答えて

0

あなたが指摘したように、製品の組み合わせの数が高すぎるため、注文側からタプルを生成して既存のタプルのみを生成することをお勧めします。

あなたがして注文をフィルタリングするために十分である必要があり、次の、あなたのフィルタの前に1不要MATCHを持っている:

MATCH (o:order) 
WITH o,size((o)-[:contains]->()) as NrProds 
WHERE NrProds >= 3 
WITH o 
... 

へ:

MATCH (o:order)-[r:contains]->(p:product) 
WITH count(r) as NrProds, o 
WHERE NrProds >= 3 // note >= sign for orders with 3 and more 
WITH o 
... 

かあれば、あなたのorderは唯一の製品のcontains関係を使用していますid、nameなどでソートすることで、同じ製品の重複をフィルタリングしないようにします(このwhere節は一意の名前/ idsに対してのみ機能します)。重複がある場合は< =そこにある)

... 
MATCH (o)-[r1:contains]->(p1:product),(o)-[r2:contains]->(p2:product),(o)-[r3:contains]->(p3:product) 
WHERE p1.name < p2.name AND p2.name < p3.name 
... 

その後、注文の数と各タプルを返す:

RETURN p1,p2,p3,COUNT(o) as c 

(あなたは、単一の順序と製品の間に複数のcontains関係を持っている場合は、COUNT(DISTINCT o)を使用する必要があります)

を最後にNタプルのみを返す:

ORDER BY c DESC LIMIT {n} 

全体のクエリ:

MATCH (o:order) 
WITH o,size((o)-[:contains]->()) as NrProds 
WHERE NrProds >= 3 
WITH o 
MATCH 
    (o)-[r1:contains]->(p1:product), 
    (o)-[r2:contains]->(p2:product), 
    (o)-[r3:contains]->(p3:product) 
WHERE p1.name < p2.name AND p2.name < p3.name 
RETURN p1,p2,p3,COUNT(o) as c 
ORDER BY c DESC LIMIT {n} 
+0

このクエリは間違いなく私のものよりもはるかに綺麗です。私のコンピュータは、私が十分に長く待っても終了します。だから、ありがとう。 "WHERE p1.name

+0

はい、重複を避けるために 'WHERE'条件があります - あなたはp1、p2、p3、p3、p2、p1、...を同一と見なします。1つのオーダーとプロダクトa、b、cを試してみて、2番目の 'MATCH'が返すもの(集計なし)、条件の半分だけを使うときに返すものを見てください。 –

関連する問題