9

neo4j でサイファー クエリを使用すると、有向循環グラフで BFS クエリと深さレベルごとに並べ替えるターゲット ノードが必要になります。

深さ内の並べ替えの場合、カスタムの「総パス コスト関数」を使用する必要があります。

  • r.followrank開始ノードと終了ノードの間のすべての関係属性。
  • 関係の方向性 (終了ノードを指す場合は followrank、そうでない場合は 0)

任意の検索深度レベルnで、 レベル で高ランクのノードにn-m, m>0接続されたノードは、 レベル で低ランクのノードに接続されたノードよりも高くランク付けされる必要がありますn-m。逆方向の場合、ランクは 0 になります (つまり、ノードとそのサブツリーは依然としてランキングの一部です)。

私はneo4j community-1.9.M01を使用しています。私がこれまでに取ったアプローチは、各エンドノードへの最短パスのフォローランクの配列を抽出することでした

このクエリの最初の素晴らしいアイデアを思いついたと思いましたが、複数のポイントでうまくいかないようです。

私のクエリは次のとおりです。

START strt=node(7)
MATCH p=strt-[*1..]-tgt
WHERE not(tgt=strt)
RETURN ID(tgt), extract(r in rels(p): r.followrank*length(strt-[*0..]-()-[r]->() )) as rank, extract(n in nodes(p): ID(n));

出力する

==> +-----------------------------------------------------------------+
==> | ID(tgt) | rank                  | extract(n in nodes(p): ID(n)) |
==> +-----------------------------------------------------------------+
==> | 14      | [1.0]                 | [7,14]                        |
==> | 15      | [1.0,1.0]             | [7,14,15]                     |
==> | 11      | [1.0,1.0,1.0]         | [7,14,15,11]                  |
==> | 8       | [1.0,1.0,1.0,1.0,0.0] | [7,14,15,11,7,8]              |
==> | 9       | [1.0,1.0,1.0,1.0,0.0] | [7,14,15,11,7,9]              |
==> | 10      | [1.0,1.0,1.0,1.0,0.0] | [7,14,15,11,7,10]             |
==> | 12      | [1.0,1.0,1.0,0.0]     | [7,14,15,11,12]               |
==> | 8       | [0.0]                 | [7,8]                         |
==> | 9       | [0.0]                 | [7,9]                         |
==> | 10      | [0.0]                 | [7,10]                        |
==> | 11      | [1.0]                 | [7,11]                        |
==> | 15      | [1.0,1.0]             | [7,11,15]                     |
==> | 14      | [1.0,1.0,1.0]         | [7,11,15,14]                  |
==> | 8       | [1.0,1.0,1.0,1.0,0.0] | [7,11,15,14,7,8]              |
==> | 9       | [1.0,1.0,1.0,1.0,0.0] | [7,11,15,14,7,9]              |
==> | 10      | [1.0,1.0,1.0,1.0,0.0] | [7,11,15,14,7,10]             |
==> | 12      | [1.0,0.0]             | [7,11,12]                     |
==> +-----------------------------------------------------------------+
==> 17 rows
==> 38 ms

それは私が必要とするものに似ていますが、問題は

  1. ノード 8、9、10、11 は 7 に対して同じ関係方向を持ちます! 逆クエリの結果...*length(strt-[*0..]-()-[r]->() )...はさらに奇妙に見えます - すぐ下のクエリを参照してください。
  2. 式の結果を 1 に正規化する方法がわかりませんlength()

方向性:

START strt=node(7)
MATCH strt<-[r]-m
RETURN ID(m), r.followrank;
==> +----------------------+
==> | ID(m) | r.followrank |
==> +----------------------+
==> | 8     | 1            |
==> | 9     | 1            |
==> | 10    | 1            |
==> | 11    | 1            |
==> +----------------------+
==> 4 rows
==> 0 ms
START strt=node(7)
MATCH strt-[r]->m
RETURN ID(m), r.followrank;
==> +----------------------+
==> | ID(m) | r.followrank |
==> +----------------------+
==> | 14    | 1            |
==> +----------------------+
==> 1 row
==> 0 ms

逆クエリ:

START strt=node(7)
MATCH p=strt-[*1..]-tgt
WHERE not(tgt=strt)
RETURN ID(tgt), extract(rr in rels(p): rr.followrank*length(strt-[*0..]-()<-[rr]-() )) as rank, extract(n in nodes(p): ID(n));
==> +-----------------------------------------------------------------+
==> | ID(tgt) | rank                  | extract(n in nodes(p): ID(n)) |
==> +-----------------------------------------------------------------+
==> | 14      | [1.0]                 | [7,14]                        |
==> | 15      | [1.0,1.0]             | [7,14,15]                     |
==> | 11      | [1.0,1.0,1.0]         | [7,14,15,11]                  |
==> | 8       | [1.0,1.0,1.0,1.0,3.0] | [7,14,15,11,7,8]              |
==> | 9       | [1.0,1.0,1.0,1.0,3.0] | [7,14,15,11,7,9]              |
==> | 10      | [1.0,1.0,1.0,1.0,3.0] | [7,14,15,11,7,10]             |
==> | 12      | [1.0,1.0,1.0,2.0]     | [7,14,15,11,12]               |
==> | 8       | [3.0]                 | [7,8]                         |
==> | 9       | [3.0]                 | [7,9]                         |
==> | 10      | [3.0]                 | [7,10]                        |
==> | 11      | [1.0]                 | [7,11]                        |
==> | 15      | [1.0,1.0]             | [7,11,15]                     |
==> | 14      | [1.0,1.0,1.0]         | [7,11,15,14]                  |
==> | 8       | [1.0,1.0,1.0,1.0,3.0] | [7,11,15,14,7,8]              |
==> | 9       | [1.0,1.0,1.0,1.0,3.0] | [7,11,15,14,7,9]              |
==> | 10      | [1.0,1.0,1.0,1.0,3.0] | [7,11,15,14,7,10]             |
==> | 12      | [1.0,2.0]             | [7,11,12]                     |
==> +-----------------------------------------------------------------+
==> 17 rows
==> 30 ms

だから私の質問は:

  1. このクエリで何が起こっているのですか?
  2. 作業アプローチはありますか?

追加の詳細については、min(length(path)) アグリゲーターを知っていますが、ベスト ヒットに関する情報を抽出しようとしているこのケースでは機能しません。ベスト ヒットについて返される追加情報は分解されます。再び結果 - それはサイファーの制限だと思います。

4

1 に答える 1

0

基本的には「パスの流れがある」関係のみを考慮してランク付けを行いたいと考えています。残念ながら、「パス フローを使用して」テストするには、各関係の開始/終了ノードのパス インデックスを確認する必要があります。これは、現時点では APOC でのみ実行できます。

// allshortestpaths to get all non-cyclic paths
MATCH path=allshortestpaths((a{id:"1"})-[*]-(b{id:"2"}))

// Find rank worthy relationships
WITH path, filter(rl in relationships(path) WHERE apoc.coll.indexOf(path, startnode(rl))<apoc.coll.indexOf(path, endnode(rl)))) as comply

// Filter results
RETURN path, REDUCE(rk = 0, rl in comply | rk+rl.followrank) as rank
ORDER BY rank DESC

(APOC 部分はテストできないので、APOC プロシージャへのパスの代わりに NODES(path) を渡す必要があるかもしれません)

于 2017-06-02T19:18:33.147 に答える