2016-12-06 5 views
0

したがって、私はリレーショナルデータベースからNeo4jグラフデータベースを作成しました。グラフデータベースには、約700万のノードと、ノード間の約900万の関係があります。大きなneo4jグラフで未接続ノードを高速検索

ここで、特定のラベルを持つノードに接続されていないノードをすべて検索したいと思います(接続されていないノードと呼ぶ)。たとえば、 "Customer"と "Order"というラベルの付いたノードがあります(これを最上位ノードと呼ぶ)。私は、これらの最上位ノードとの間に関係のないすべてのノードを見つけたいと思っています。この関係は直接的である必要はなく、ノードは他のノードを介してトップレベルノードに接続することができる。

私はこの問題を解決するCYPHERクエリを持っています。

MATCH (a) WHERE not ((a)-[*]-(:Customer)) AND not ((a)-[*]-(:Order)) RETURN a; 

あなたが想像できるように、クエリの実行には長い時間が必要になり、パフォーマンスが悪いです。ほとんどの場合、無向の関係のために、関係がいくつあるかによって問題にならないためです。しかし、関係の方向は重要ではありません。どのノードからトップレベルノードのいずれかへのパスがないことを確認する必要があります。

未接続ノードをより早く見つける方法はありますか?データベースは本当に大きく、トップレベルノードをマークする2つ以上のラベルがあることに注意してください。

答えて

0

より多くの操作が必要ですが、パフォーマンスを向上させるためにバッチで実行できます(APOCプロシージャライブラリのapoc.periodic.commit()を参照)。

考えられるのは、グラフ内のすべてのノード(apoc.periodic.commitでバッチ実行)にラベル(例:Unconnected)を適用し、そのラベルを持つ最上位ノードのバッチを取得してからサブグラフ内のすべてのノードがそれらから延びてそのラベルを削除します。

最終的に:接続されていないラベル(すべての最上位ノードとそのサブグラフにこのラベルがないことを意味します)を持つ最上位ノードが使い果たされた場合、未接続ラベル付きグラフに残っている唯一のノードは接続されませんあなたのトップレベルのノードに。

この種の操作に対するアプローチはおそらく遅くなりますが、これをバッチ処理でき、中断した場合は再開できるという利点もあります。クエリーが完了すると、関連するすべての未接続ノードには、以後の処理のためにラベルが付けられます。

また、Neo4jの無関係の関係の最後の1つの注釈は、構文() - [*] - ()内に矢印がありません。

+0

私はこれは素晴らしい解決策だと思います、ありがとうございました。私は、トップレベルのノードに接続されているすべてのノードを削除し、グラフ内の未接続ノードだけを残して同様のアプローチを試したかったのです。あなたのアプローチははるかに良いです。 また、APOC手順に言及してくれてありがとう、私はそれがCypherを介してバッチで操作を実行することが可能であることを知らなかった。 構文修正のおかげで、私はそれを編集します。 私はこのアプローチを試して、完了したらフィードバックを与えます。 –

0
MATCH (a) 
WHERE 
not (a:Customer OR a:Order) 
AND shortestPath((a)-[*]-(:Customer)) IS NULL 
AND shortestPath((a)-[*]-(:Order)) IS NULL 
RETURN a; 

rel-typesを追加できる場合は、より高速になります。 もう1つの最適化は、ノードの顧客パス:注文ノードをチェックすることであり、その逆もあります。すなわち、一般に

NONE(n in nodes(path) WHERE n:Order)

、これはすなわち が二組 に並列にすべての注文および顧客ノードを周りに展開して2つのセットの間のオーバーラップを計算する、むしろセット動作かもしれません。

次に、ノードの総数からオーバーラップを削除します。

私はそのような機能を追加するために、ここでAPOCのための問題を追加

またはプロシージャ

https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/223

+0

クエリにエラーがあります。 shortestPath()にはノード名が必要です。 rel-typesについては、私のユースケースでは関係ないので、rel-typesは使用できません。 パスを確認して重複を削除するなど、何を意味するのかよく分かりません。あなたは詳しく説明できますか?私が理解している限り、あなたは:Orderノードで始まり、接続されたノードでCustomerノードを確認することをお勧めします。その他の注文および顧客ノードの場合も同様です。それを使うのはどういうものなのでしょうか、結果として重なり合って何ができるのでしょうか? –

関連する問題