2017-02-11 10 views
0

私はNeo4jを使い始めており、最大kエッジ(k回までの友人の友人)の長さで別のノードに接続されたノードを見つけることについて不思議です。 Neo4j自体のチュートリアルの例を使って説明します(私はグラフ作成コマンドを下に置いています)。Cypherはすべてのパスを列挙しないようにします

match (e {name:"Emil"})-[*1..2]-(p) 
return DISTINCT e, p; 

このクエリは、Emilに接続されているノードとそれらのノードに接続されているノードを返します。私の問題は、すべてのパスを列挙しても気にしませんが、Emilから長さ1-2のすべてのパスを列挙しているようです。クエリから、私はその距離にあるEmilに接続されているノードだけを気にして、すべての可能なパスを列挙することは、そのクエリを実現するための貧弱な方法です。これは、複雑さが圧倒的になるにつれて、大規模で密なグラフの問題です。

DISTINCTを削除すると、8個のレコードが作成されます。これはEmilの1〜2の長さのパスの数です。大きなグラフのテストに基づいて、DISTINCTはクエリの実行時間に影響を与えない後処理ステップだと思われますが、冗長出力は削除されます。あれは正しいですか?

私の主な質問は、この問題のためのCypherクエリを作成する方法があるため、すべての一意のパスを通過せず、複雑さを減らすことができますか?どこかに誤解があるかどうか教えてください。

----ネオで

CREATE (ee:Person { name: "Emil", from: "Sweden", klout: 99 }) 
CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }), 
(ir:Person { name: "Ian", from: "England", title: "author" }), 
(rvb:Person { name: "Rik", from: "Belgium", pet: "Orval" }), 
(ally:Person { name: "Allison", from: "California", hobby: "surfing" }), 
(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir), 
(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb), 
(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally), 
(rvb)-[:KNOWS]->(ally) 

答えて

0

マックス・デ・Marziは、クエリのこれらの種類、唯一興味があるので、可変長の試合についての素晴らしいblog postを書いた-----グラフを作成するコマンドパスではなく別個のノードについては、今後のリリースではクエリ・プランナによって検出され最適化されます。

一方、一意性パラメータとして 'NODE_GLOBAL'を指定すると、APOCプロシージャにはapoc.path.expandConfig()コールの解決策があります。

これにより、パス拡張中に見つかったノードが1回しかアクセスされないため、同じノードに複数のパスが表示されないようにします。

match (e {name:"Emil"}) 
call apoc.path.expandConfig(e, {maxLevel:2, uniqueness:'NODE_GLOBAL'}) yield path 
WITH e, last(nodes(path)) as subgraph 
where e <> subgraph 
return e, subgraph; 
+0

ありがとうございました!どちらも私が探しているものです。 – steve

関連する問題