2017-04-22 7 views
1

Neo4jを使用して、特定のノード "a"に接続されていないノードを見つけようとしています。これまで私が持っていたクエリは:Neo4j Cypherは2つのディスジョイントノードを見つける

MATCH p = shortestPath((a:Node {id:"123"})-[*]-(b:Node)) 
WHERE p IS NULL 
RETURN b.id as b 

したがって、aとbの間の最短経路を見つけようとします。パスが見つからない場合は、そのノードのIDを返します。しかし、これにより、クエリが数分実行され、メモリ不足のときにクラッシュします。私はこの方法がうまくいくかどうか、もっと効率的な方法があれば疑問に思っていましたか?どんな助けでも大歓迎です!

編集:

MATCH (a:Node {id:"123"})-[*]-(b:Node), 
(c:Node) 
WITH collect(b) as col, a, b, c 
WHERE a <> b AND NOT c IN col 
RETURN c.id 

だから、COL(コレクト(b)参照)cは、その後、Cが接続されていないCOLにないのであれば、に接続されているすべてのノードが含まれていますか?

答えて

1

このMATCHには、実行するための不可能な述語が与えられているため、最短パスは決して見つかりません。

WHERE句はMATCH、OPTIONAL MATCH、およびWITH句に関連付けられているため、パスは存在しない最短パスを尋ねます。それは何も返さないでしょう。

また、shortestPathは、接続したくないノードから開始するため、接続されていないノードを見つける方法がありません。

おそらく最も簡単な方法は、問題のノードに接続されているすべてのノードにMATCHし、すべてに一致させることです。ノードは接続されていないセットをチェックします。つまり、コレクション内のメンバーシップチェックだけで、db内のすべての単一ノードから最短のパスを実行する必要はありません。

これはサブグラフ内のノードとのマッチングが最も速いため、APOC Proceduresが必要です。

MATCH (a:Node {id:"123"}) 
CALL apoc.path.subgraphNodes(a, {}) YIELD node 
WITH collect(node) as subgraph 
MATCH (b:Node) 
WHERE NOT b in subgraph 
RETURN b.id as b 

EDIT

編集したクエリが、それは巨大な結果セットを(生成するために起こって爆破する可能性がある中でユニークなパスで、あなたの開始ノードから到達可能なすべてのノードの結果セットを構築するクエリevery:Nodeを含むデカルト積)。

代わりに、別々のノードを収集してください(そうでなければ、異なるノードを経由して到達できる同じノードの倍数が得られるため)。リストにないノード。

MATCH (:Node {id:"123"})-[*0..]-(b:Node) 
WITH collect(DISTINCT b) as col 
MATCH (a:Node) 
WHERE NOT a IN col 
RETURN a.id 
+0

ありがとうございます。私はAPOC手順を使用することはできません。これは代替品として見えますか? (編集を参照) – ThatOneGuy

+0

代替クエリを修正する必要があるクエリで私の回答を編集しました。 Cypherは一意のパスに関心があるので、Cypherの可変長一致はAPOCのsubgraphNodes()プロシージャほど効率的ではないため、このクエリは大きなグラフでもタイムアウトする可能性があります。 – InverseFalcon

関連する問題