Cypher: Matching nodes at arbitrary depth via a strictly alternating set of relations

十年热恋 提交于 2019-12-12 05:08:52

问题


I'm quite new to Cypher but struggling to find how to do this. I want to generalise the following so that it will match at an arbitrary depth.

MATCH (:start)-[:a]-()-[:b]-(:end) //Depth1
MATCH (:start)-[:a]-()-[:b]-()-[:a]-()-[:b]-(:end) //Depth2
MATCH (:start)-[:a]-()-[:b]-()-[:a]-()-[:b]-()-[:a]-()-[:b]-(:end) //Depth3
MATCH (:start)-[:a]-()-[:b]-()-[:a]-()-[:b]-()-[:a]-()-[:b]-()-[:a]-()-[:b]-(:end) //Depth4

In other words, the path needs to pass through any number of a-node-b in strict alternation; a-node-a etc. will not work. So I can't do this, as per Neo4J: find a sub-graph of arbitrary depth with nodes connected by a given set of relations?

MATCH (:start)-[:a|b*]-(:end)

because that would match things like this:

MATCH (:start)-[:a]-()-[:a]-(:end)
MATCH (:start)-[:b]-()-[:b]-(:end)

Does anyone know how to solve this? I'm using Cypher with Neo4j 2.x if it matters.

Thanks!


回答1:


The strict answer is no, this is not possible in Cypher. The stretched answer is: it's possible to determine whether such a path exists, and to return the nodes on either end of the path, but it's slow and you won't get to keep some of the information along the path.

MATCH (first) - [:a] -> () - [:b] -> (third)
MERGE (first) - [temp:c] -> (third)
WITH COLLECT(temp) AS temps
MATCH p = (:start) - [:c*] -> (:end)
WITH temps, COLLECT(p) AS ps
FOREACH(temp IN temps)|DELETE temp)
UNWIND ps AS p
RETURN DISTINCT p

This does require you to have a :c or other relationship type that you can use as a temp here.



来源:https://stackoverflow.com/questions/40330729/cypher-matching-nodes-at-arbitrary-depth-via-a-strictly-alternating-set-of-rela

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!