Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j 所有没有循环的路径_Neo4j_Cypher - Fatal编程技术网

Neo4j 所有没有循环的路径

Neo4j 所有没有循环的路径,neo4j,cypher,Neo4j,Cypher,我很难获得节点之间没有循环的所有可能路径。我使用neo4j 3.0.4。我准备了一个例子,但首先是一个简短的解释。我有从A到Z的节点。这些节点可以以各种方式连接。我想得到所有可能的没有循环的路径,这意味着一个特定的节点不会被访问一次以上 下面是一个例子: CREATE (newNode {name:'A'}) RETURN newNode; CREATE (newNode {name:'B'}) RETURN newNode; CREATE (newNode {name:'C'}) RETU

我很难获得节点之间没有循环的所有可能路径。我使用neo4j 3.0.4。我准备了一个例子,但首先是一个简短的解释。我有从A到Z的节点。这些节点可以以各种方式连接。我想得到所有可能的没有循环的路径,这意味着一个特定的节点不会被访问一次以上

下面是一个例子:

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。 AllShortestPath对我不起作用,因为它只提供跳数最少的路径。但是我想得到所有没有循环的路径,跳数是不相关的。由于查询非常昂贵,因此有必要限制结果或路径长度

path = (from)-[r*20]->(to)
但这不是避免循环的解决方案,因为它们也可能发生在短路径中

编辑1: 好的,现在我提出了一个可能的解决方案:

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,好的。我测试了这个,它是有效的。无论如何谢谢你!:)顺便说一句,由于您熟悉apoc,在3.1版中使用用户定义的函数将变得更容易:您的过滤器将变成
,其中size(apoc.coll.toSet(NODES(path))=size(NODES(path))
。如果你回顾过去,你会发现这是一个棘手的问题,但它肯定会变得更好。