2017-06-02 7 views
1

私は、多くの開始ノードa、b、cに関連する共通ノード 'x'を探す簡単なクエリを持っています。 a、b、cの共通ノードxがない場合は、共通ノード「y」と「z」のそれぞれa、b、b、cをそれぞれ比較したいと思います。これは私がそれが見えると想像する方法です...もちろん、動作しません。MATCHでのケースの使用

MATCH p1=(a)-[]->(x) WHERE a.n=1 
WITH p1,a,x 
MATCH p2=(b)-[]->(x) WHERE b.n=2 
WITH p1,p2,a,b,x 
MATCH p3=(c)-[]->(x) WHERE c.n=3 
WITH p1,p2,p3,a,b,c,x 
MATCH CASE WHEN x IS NULL THEN p4=(a)-[]->(y)<-[]-(b) WHERE a.n=1 AND b.n=2 END 
WITH p1,p2,p3,p4,a,b,c,x,y 
MATCH CASE WHEN x IS NULL THEN p5=(b)-[]->(z)<-[]-(c) WHERE b.n=2 AND c.n=3 END 
RETURN p1,p2,p3,p4,p5,x,y,z 

私は共通の「x」が見つかった場合はC、冗長性を削減し、ペアで、B bを検索する必要がないため、クエリをスピードアップするためにCASEを使用してで探しています。どのようにCASEを使ってMATCHを作成しますか?おそらく、CASEを使うよりも良い方法がありますか?

QUESTION背景

I深い15個のノードを平均かなり浅い非常に大きなデータセットを持っています。私はネットワーク内の共通の関連ノードの形で複数の入力間の相関関係を探しています。入力は2から20までの連続した値を取ることができ、それらの順序は関連して一緒にグループ化する傾向があるという点で関連しています。多くの場合、すべての入力には共通の関連ノードがありますが、そうでなければ共通のノード、すなわち入力1,2を持つ他の順次グループを見つける必要があります。 2,3 |それで、ワイドにスタートして作業をするか、次の入力を一度に1つずつペアと比較して最後の結果と比較するかどうかという問題です。私はCASEを使用して、結果が見つからない場合の入力を処理するグループを決定することを望んでいました。

ネットワークを構成する限り、最小の関係数を持つ各ノードでは浅いので、メタノードを追加すると役立ちません。入力グループを結合して単一の開始ノードを持つと、開始ノードの数が指数関数的に増加します。この時点では、入力可能な入力ごとに1つがあります.1000万程度です。それらを組み合わせると指数関数的に増加するので、避けるのが最善だと私は考えています。開始ノードがクエリの中で最も高価な部分であることが分かっているからです。申し訳ありませんが、私はビジネスの事例について話し合うつもりはありません。

答えて

2

このクエリは、x、y、z値のコレクションを返す必要があります。 xsコレクションが空でない場合は、ysコレクションとzsコレクションを無視することができます。

MATCH (a {n: 1}), (b {n: 2})-->(w), (c {n: 3}) 
OPTIONAL MATCH pa=(a)-->(w) 
WITH a, b, c, COLLECT(DISTINCT NODES(pa)[1]) AS ys 
OPTIONAL MATCH pc=(c)-->(w) 
WITH a, b, c, ys, COLLECT(DISTINCT NODES(pc)[1]) AS zs 
RETURN a, b, c, apoc.coll.intersection(ys, zs) AS xs, ys, zs; 

あなたのユースケースについて注意する興味深いのは、bノードは、すべての3つのコレクションの内容を決定するために必要とされることです。したがって、MATCH節はbノードに関連するノードを見つけ、他の(オプションの)一致をそれらのノードのみを考慮して制限します。これによりクエリが高速化されます。 apoc.coll.intersectionyszsのコレクションを交差させてxsコレクションを取得するために使用されます。

我々はデカルト積を回避することができるように、[EDITED]

代わりの(第2の任意の一致の後に)同時に両方COLLECT操作を行うには、我々は、右の第1、オプションの一致の後の最初のCOLLECT動作を行います。これにより、クエリが高速化され、メモリ要件が削減されます。 APOCへのアクセスのない人のために

+0

の平野サイファーバージョンはあなたに感謝です。可能であれば2ノードのマッチングを避けようとしていました。おそらく1000行を返す可能性がありますが、3ノードのマッチは数行しか返しません。APOCバージョンはインストールされていませんが、最初にすべての開始ノードで一致を試すのではなく、1000個の行に一致するのが最も速いと感じますか?この例では、3つの開始ノードがありますが、使用中は20になる可能性があります。 – Damon

+2

ユースケースの詳細を説明するために質問を更新できますか?そうでなければ良い答えを提供する方法はありません。 (例えば、20のノードがある場合、可能なノードのグループ化は何ですか?)結果を効率的に取得するためにデータを構造化する別の方法があるかもしれませんが、ユースケースを知る必要があります。 – cybersam

+0

ありがとう、私はデータの詳細情報で質問を更新しました。 – Damon

2

、ここサムスanswer

// Get Start Nodes 
MATCH (a {n: 1}), (b {n: 2}), (c {n: 3}) 

// Find common nodes for ab and cb 
OPTIONAL MATCH (a)-->(ab)<--(b) 
OPTIONAL MATCH (c)-->(cb)<--(b) 

// Aggregate common nodes of ab and cb 
WITH a, b, c, COLLECT(ab) AS ab, COLLECT(cb) AS cb 

// Return with additional Aggregate of intersection of the lists ab and cb 
RETURN a, b, c, filter(n in ab WHERE n IN cb) as abc, ab, cb 
+0

ありがとうございます。私はバージョン2.3ですので、APOCはありません。私はエラーが発生しています: "タイプの不一致:期待されたパスがあったが、コレクションでした(行5、列35) " abc、abのようにa、b、c、フィルタ(NODES(ab) cb "" – Damon

+0

@Damon申し訳ありませんが、習慣。 abの代わりにNODES(ab)をしました(abはすでにノードのリストです)。 – Tezra

関連する問題