2017-12-19 18 views
1

Neo4jを使ってあるノードに近いノードを取得したいと思います。Neo4j - 近くのノードセットを見つける

Techniques that take edge costsが一般的ですが、ノードコストを使用する方法はありません。

例えば、this sample Graphでは、ノードAの近傍のノードは、総コストは15

  • 内コストB、C、E、G、H、Iを

    • あるれますのAは含まれていません。
    • エッジ方向は無視できます。

    サンプルグラフのノード間の最小コストは、次のようになります。

    A<->B : 3 
    A<->C : 8 
    A<->D : 50 
    A<->E : 10 
    A<->F : 16 
    A<->G : 11 
    A<->H : 13 
    A<->I : 14 
    

    サンプルグラフは、次のクエリで作成できます。

    CREATE 
    (a:Node{name:"A",cost:10}), 
    (b:Node{name:"B",cost:3}), 
    (c:Node{name:"C",cost:5}), 
    (d:Node{name:"D",cost:50}), 
    (e:Node{name:"E",cost:10}), 
    (f:Node{name:"F",cost:8}), 
    (g:Node{name:"G",cost:1}), 
    (h:Node{name:"H",cost:2}), 
    (i:Node{name:"I",cost:1}), 
    (a)-[:Edge]->(b), 
    (b)-[:Edge]->(c), 
    (a)-[:Edge]->(d), 
    (a)-[:Edge]->(e), 
    (c)-[:Edge]->(f), 
    (d)-[:Edge]->(f), 
    (e)-[:Edge]->(g), 
    (g)-[:Edge]->(h), 
    (h)-[:Edge]->(i), 
    (f)-[:Edge]->(i); 
    

    コメント欄にI rebuilt the graphとしています。コストを計算するエッジが追加されました。

    MATCH (n)-[]-(m) 
    MERGE (n)-[r:COST{cost:m.cost}]->(m) 
    

    そして、次のクエリを実行しました。

    MATCH(startNode:Node{name:"A"}),(endNode:Node) 
    CALL algo.shortestPath(startNode, endNode, "cost",{relationshipQuery:'COST', defaultValue:1.0,write:false,direction:'OUTGOING'}) 
    YIELD nodeCount, totalCost 
    WITH nodeCount, totalCost, endNode 
    WHERE totalCost <= 15 
    RETURN nodeCount, totalCost, endNode 
    ORDER BY totalCost ASC; 
    

    私は期待した結果を得ました。

    ╒═══════════╤═══════════╤══════════════════════╕ 
    │"nodeCount"│"totalCost"│"endNode"    │ 
    ╞═══════════╪═══════════╪══════════════════════╡ 
    │0   │-1   │{"name":"A","cost":10}│ 
    ├───────────┼───────────┼──────────────────────┤ 
    │2   │3   │{"name":"B","cost":3} │ 
    ├───────────┼───────────┼──────────────────────┤ 
    │3   │8   │{"name":"C","cost":5} │ 
    ├───────────┼───────────┼──────────────────────┤ 
    │2   │10   │{"name":"E","cost":10}│ 
    ├───────────┼───────────┼──────────────────────┤ 
    │3   │11   │{"name":"G","cost":1} │ 
    ├───────────┼───────────┼──────────────────────┤ 
    │4   │13   │{"name":"H","cost":2} │ 
    ├───────────┼───────────┼──────────────────────┤ 
    │5   │14   │{"name":"I","cost":1} │ 
    └───────────┴───────────┴──────────────────────┘ 
    

    私は、私が実際に使用して、データベース内の類似したクエリを実行したときしかし、私が原因の計算の膨大な量にそれを行うことができませんでした...

    Failed to invoke procedure `algo.shortestPath`: Caused by: java.lang.ArrayIndexOutOfBoundsException: -1340037571 
    

    誰でもへのアイデアを持っています近くのノード集合を効率的に探索する?

  • +0

    サイファークエリを実行して、ノードへのすべての受信エッジを更新し、エッジの重みをノードの重みに設定するのはどうでしょうか?次に、標準的なエッジ加重アプローチは、あなたが望むように動作するはずです。 – FrobberOfBits

    +0

    コメントありがとうございます。サンプルグラフを再構築すると、グラフで正しく機能しました。しかし、計算の複雑さは、私が実際に適用したいデータベース上で巨大になっています...詳細については、編集した質問を見てください。 – tekunikaruza

    答えて

    1

    あなたはこのCYPHERクエリでそれを行うことができます。

    MATCH p=(start {name:"A"})-[r*..10]-(end {name:"I"}) 
    RETURN reduce(x=0, n IN tail(nodes(p)) | x + n.cost) AS cost 
    ORDER BY cost ASC 
    LIMIT 1 
    

    しかし、この場合には、のNeo4jは、それがグローバルなコストを計算し、startend間のすべての既存のパスを検索します。したがって、高価なクエリです...

    パフォーマンスを必要とする場合は、グラフ/アルゴからalgo.shortestPath関数の実装を見て、独自のプロシージャ/ algoを作成する必要があります。

    関連する問題