2016-11-15 10 views
0

Cypherを使用する場合、次のクエリは実際には必要なすべてのパスをトラバースします。Cypherのトラバーサル時間を制限する方法は?

START n=node(0) 
MATCH (n)-[]-(p1:Person) 
RETURN n 

しかし、私が望むのは、1つのサブグラフが見つかるとトラバースを停止し、結果が一致したことを伝えます。どうやってするか? MATCHを超えてLIMITを付与するといいですか?しかし、限り私はを知って、LIMITRETURNでないMATCHでのみ動作します。

答えて

2

LIMITを使用すると、Neo4jは一致するものが見つかるとグラフの移動を停止します。

Cypherは宣言型のクエリ言語であるため、クエリオプティマイザはLIMIT節を適切に処理します。つまり、パターンマッチング中の制限を考慮します。

これを証明するための実験を設計しましょう。例えば、データセット:

Example graph

まず、それはものではありません特定のIDにノードnをバインドしてクエリからSTART句を削除します。

CREATE 
    (p1:Person), 
    (p2:Person), 
    (p3:Person), 
    (p1)-[:KNOWS]->(p2), 
    (p1)-[:KNOWS]->(p3), 
    (p2)-[:KNOWS]->(p3) 

グラフは次のようになります私たちはこの実験に欲しいです。一般的に:STARTは既に非難されており、可能な場合は使用しないでください。

のは、LIMIT 1制約を追加して、クエリプランを分析するためにPROFILEキーワードを使用してみましょう:

PROFILE 
MATCH (n)-[]-(p1:Person) 
RETURN n 
LIMIT 1 

Query plan with LIMIT 1

LIMITキーワードを削除し、再度、クエリプランを分析:

PROFILE 
MATCH (n)-[]-(p1:Person) 
RETURN n 

Query plan without LIMIT

LIMIT 1制約付きクエリプランは、NodeByLabelScan操作から2つのデータベースヒットを含む1行のみを返します。ただし、制約のないクエリプランでは、データベースのヒット数が4の3行が返されます。

更新: InverseFalconのコメントで示唆されているように、EXISTS関数を使用すると、ブール値になります。ただし、結果に1行を取得するには(まだ不必要なデータベースのヒットを避けるため)、まだLIMIT 1が必要です。

PROFILE 
MATCH (n) 
RETURN EXISTS((n)-[]-(:Person)) 
LIMIT 1 

enter image description here

+1

この試合の唯一の目的は、このようなパターンまたはパスが存在するかどうかを把握することである場合にも、EXISTS()関数に興味があるかもしれません。 – InverseFalcon

+0

ありがとう@InverseFalcon、それは非常に洞察力があります。私は 'EXISTS'を使って答えを更新しました。興味深いのは、まだ 'LIMIT 1'を使うべきだと思うということです。 'EXISTS'にもっと優雅な方法がありますか? –

+1

それは本当にどのようにクエリで使用されるかによって異なります。特定のノードに一致する場合(元のクエリでノード(0)と同じように)パターンが存在するかどうかを知りたい場合は、そのパターンでEXISTS()を使用すると、trueまたはfalse 。多くのノード(この回答のクエリのように、nがすべてのノードに一致する)と一致する場合に使用すると、すべての行についてそのパターンEXISTS()が計算されます。 LIMITは結果セット全体に適用され、行単位ではないことに注意してください。 – InverseFalcon

関連する問題