我希望在经过给定节点的图上获得所有的simple cycles/circuits。通过这个密码查询,我可以这样做:
MATCH p=(n)-[*]->(n)
WHERE n.postId = 71 //postId is a node property
RETURN nodes(p)然而,根据图论,上述检索电路中的重复节点(从开始和结束节点除外)根本不是一个电路。
使用下面的查询,我可以删除电路中的那些重复,但是我必须限制MATCH模式中的电路或路径的长度,这是一种硬编码。
// In this example the length of the path is hardcoded to 4
MATCH p=
(n)-[:RELATES_TO]->
(p2)-[:RELATES_TO]->
(p3)-[:RELATES_TO]->
(p4)-[:RELATES_TO]->(n)
WHERE n.postId = 71
AND p2.postId <> 71
AND p3.postId <> 71
AND p4.postId <> 71
RETURN nodes(p)是否有一种方法来过滤第一个查询中的关系之间的节点?
MATCH p=(n)-[*]->(n)
WHERE n.postId = 71 //postId is a node property
RETURN nodes(p)重要说明:
发布于 2017-09-01 19:44:49
你试过使用filter()或none()吗?我认为我正确地理解了您的问题,但下面是我如何使用上述功能。(如果这是关的,那就顺势而行。)
要点:http://console.neo4j.org/?id=99xkcu
CREATE
(g:Person {name: 'Gorduin'}), (a:Person {name: 'Alvaro'}),
(pn:PhoneNumber {number: '555-512-2017'}),
(e11:Extension {extension: 11}),
(e27:Extension {extension: 27}),
(e19:Extension {extension: 19}),
(e11)-[:extension_of]->(pn)<-[:extension_of]-(e27),
(e19)-[:extension_of]->(pn),
(g)<-[:phone_number_of]-(e11),
(g)<-[:phone_number_of]-(e27),
(a)<-[:phone_number_of]-(e19),
(a)<-[:phone_number_of]-(pn);

需要使用可变长度查询,因为:phone_number_of指针可以来自扩展名(链接到电话号码)或电话号码本身。箭头方向不重要,您可以反转它们中的任何一个,然后尝试下面的查询。
(在我的情况下,限制查询的长度是显而易见的解决方案,例如 匹配路径=(p:Person)-*1.3-(n:PhoneNumber)返回节点(路径); 但这不是OP的问题。)
(1)从人到电话号码的每一条可能的路径(为可读性而编辑):
MATCH path = (p:Person)-[*]-(n:PhoneNumber)
RETURN nodes(path) as every_possible_path_from_a_Person_to_a_PhoneNumber;
╒══════════════════════════════════════════════════════════════════════╕
│"every_possible_path_from_a_Person_to_a_PhoneNumber" │
╞══════════════════════════════════════════════════════════════════════╡
│[a,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[g,e11,pn,e19,a,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[g,e27,pn,e19,a,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[g,e11,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[a,pn,e27,g,e11,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[a,e19,pn,e27,g,e11,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[a,e19,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[g,e11,pn,a,e19,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[g,e27,pn,a,e19,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[g,e27,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[a,pn,e11,g,e27,pn] │
├──────────────────────────────────────────────────────────────────────┤
│[a,e19,pn,e11,g,e27,pn] │
└──────────────────────────────────────────────────────────────────────┘(2)通过过滤出包含特定节点(具有特定属性或标签的节点)的路径,使用none()消除冗余:
MATCH path = (p:Person)-[*]-(n:PhoneNumber)
WITH nodes(path) as ns
WHERE NONE(node IN ns WHERE (exists(node.name) and node.name ='Gorduin'))
RETURN ns as path_nodes_NOT_containing_a_specific_person;
╒══════════════════════════════════════════════════════════════╕
│"path_nodes_NOT_containing_a_specific_person" │
╞══════════════════════════════════════════════════════════════╡
│[a,pn] │
├──────────────────────────────────────────────────────────────┤
│[a,e19,pn] │
└──────────────────────────────────────────────────────────────┘(3)使用filter()从返回路径中删除特定节点:
MATCH path = (p:Person)-[*]-(n:PhoneNumber)
WITH nodes(path) as ns
WHERE NONE(node IN ns WHERE (exists(node.name) and node.name ='Gorduin'))
RETURN filter(node in ns WHERE NOT node:Person) as personless_nodelist;
╒══════════════════════════════════════════════════════════════╕
│"personless_nodelist" │
╞══════════════════════════════════════════════════════════════╡
│[pn] │
├──────────────────────────────────────────────────────────────┤
│[e19,pn] │
└──────────────────────────────────────────────────────────────┘发布于 2016-08-31 20:46:53
您可能需要尝试APOC,特别是图算法部分中的allSimplePaths函数。简单路径不应该有重复的节点。
编辑
注意,目前该算法不能用于查找开始节点和结束节点相同的简单循环。
但是,如果将结束节点定义为周期中的第二到最后一步,那么所有与开始节点有定向关系的开始节点都应该能够得到结果(尽管路径显然不会包括对开始节点的最后遍历以完成周期)。
发布于 2016-08-31 22:22:04
虽然这可能不像@InverseFalcon建议的那样使用allSimplePaths APOC过程(我还没有尝试过),但在纯Cypher中可以获得简单的路径:
MATCH p=(n)-[*]->(n)
WHERE n.postId = 71
WITH NODES(p) AS nds
UNWIND nds AS nd
WITH nds, COUNT(DISTINCT nd) AS dnd
WHERE dnd = LENGTH(nds)-1
RETURN nds;基本上,此查询要求路径中不同节点的数目等于节点数减去1(因为最后一个节点必须与第一个节点相同)。
https://stackoverflow.com/questions/39258523
复制相似问题