我希望在通过给定节点的图表上获取所有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)
重要说明:
答案 0 :(得分:0)
您可能想要试用APOC程序库,特别是图算法部分中的allSimplePaths函数。简单路径应该没有重复节点。
修改
请注意,目前该算法目前无法用于查找起始节点和结束节点相同的简单循环。
但是,如果将结束节点定义为循环中倒数第二步,将起始节点的所有相邻节点定义为与起始节点具有定向关系,那么您应该能够获得结果(虽然路径显然不包括最终遍历到起始节点以完成循环)。
答案 1 :(得分:0)
虽然这可能没有使用allSimplePaths APOC程序那么快,正如@InverseFalcon所建议的那样(我还没有尝试过),这里有一个在纯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;
基本上,此查询要求路径中 distinct 节点的数量等于节点数减1(因为最后一个节点必须与第一个节点相同)。
答案 2 :(得分:0)
您是否尝试过使用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
指针可以来自扩展名(链接到电话号码)或电话号码本身。箭头方向无关紧要,您可以撤消其中任何一个并尝试以下查询。
(限制查询的长度将是我的明显解决方案 例如
MATCH path = (p:Person)-[*1..3]-(n:PhoneNumber) RETURN nodes(path);
但这不是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] │
└──────────────────────────────────────────────────────────────┘