ループのないノード間のすべての可能なパスを取得するのに問題があります。私はneo4j 3.0.4を使用します。私は例を用意しましたが、まず短い説明がありました。私はAからZまでのノードを持っています。これらのノードはそれぞれの方法で接続できます。私はループなしですべての可能なパスを取得したい、特定のノードが複数回訪問されていないことを意味します。ここでCypher:ループのないすべてのパス
例:
CREATE (newNode {name:'A'})
RETURN newNode;
CREATE (newNode {name:'B'})
RETURN newNode;
CREATE (newNode {name:'C'})
RETURN newNode;
CREATE (newNode {name:'D'})
RETURN newNode;
CREATE (newNode {name:'E'})
RETURN newNode;
CREATE (newNode {name:'Z'})
RETURN newNode;
MATCH (n1), (n2)
WHERE n1.name = 'A' AND n2.name = 'B'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'A' AND n2.name = 'C'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'B' AND n2.name = 'C'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'C' AND n2.name = 'D'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'D' AND n2.name = 'E'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'E' AND n2.name = 'Z'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'D' AND n2.name = 'Z'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'D' AND n2.name = 'A'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH (n1), (n2)
WHERE n1.name = 'B' AND n2.name = 'A'
CREATE
(n1)-[r:CONNECTED_TO]->(n2)
RETURN n1, n2, r;
MATCH p=(from{name:'A'}), (to{name:'Z'}),
path = (from)-[r*]->(to)
RETURN path
私は最後のクエリを実行する場合、私はまた、A-> B-> A-> C-> D-> Zのようなパスを取得します。私はこのループA→B→Aを避けたい。 allShortestPathsは、ほんの少しのホップだけでパスを提供するため、私にとっては機能しません。しかし、私はループなしですべてのパスを取得したい、ホップの数は関係ありません。クエリが非常に高価であるため、結果またはパスの長さを制限する必要があります。
path = (from)-[r*20]->(to)
しかし、これはショートパスでも発生する可能性があるため、ループを回避する方法ではありません。
EDIT1: [OK]を、今私は、このための可能な解決策を考え出す:
MATCH (from{name:'A'}), (to{name:'Z'}),
path = (from)-[:CONNECTED_TO*]->(to)
WHERE NONE (n IN NODES(path) WHERE SIZE(FILTER(x IN NODES(path) WHERE n = x))> 1)
RETURN path, LENGTH(path) as length
ORDER BY length;
このクエリは、動作しているようですが、私はそれが非常に高価であることを前提としています。誰かがより良いソリューションを提供できるか?
WHERE ALL(x IN NODES(path) WHERE SINGLE(y IN NODES(path) WHERE y = x))
をしかし、私はあなたが基本的に、より効率的な方法を見つけることができます信じていません:あなたはこのように変更した場合
Hmm、ok。私はこれを試して、それは動作します。とにかくありがとうございました! :) – Stefan
Btwは 'apoc'に慣れているので、ユーザ定義関数でリリース3.1よりはるかに簡単になるでしょう:フィルタは' WHERE size(apoc.coll.toSet(NODES(path) ))= size(NODES(path)) 'である。 [history](http://stackoverflow.com/questions/13767748/returning-only-simple-paths-in-neo4j-cypher-query)を振り返ってみると、それは難しい問題だとわかるでしょうが、間違いなくより良い。 –