Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-17-2019 11:38 PM
For example:
Situation 1:
(a) - [:CONNECTED] -> (z)
result 1:
(a) - (b) - (c) - (d) - (stop) - (e) - (f) - (z)
Now as the stop node came between the result, I want the following result:
(a) - (b) - (c) - (d) - (stop)
Situation 2:
(a) - [:CONNECTED] -> (x)
result:
(a) - (b) - (c) - (d) - (e) - (f) - (x)
Now as the stop node is not present between the result, I want the whole result:
(a) - (b) - (c) - (d) - (e) - (f) - (x)
Can one one help me on this?
Thank you
Solved! Go to Solution.
11-26-2019 03:30 PM
Here are a few queries to get you going on your solution.
This is the simplest one. Look for a path, p, that starts at 'A' and ends at a node with either 'Z' or 'stop'. Then return only the shortest of all of the matches if there are multiple. The theory here is that if the 'stop' is encountered first it will stop there.
MATCH p=(a:Node {name: 'A'}) - [:CONNECTED*] -> (end:Node)
WHERE end.name in ['stop','Z']
RETURN p
ORDER BY length(p)
LIMIT 1
Here is a another pure cypher example. This one finds the path from A..Z first and then looks for a stop node afterwards. If there is/are stop node(s) it collects them and then uses the first one to only return from the beginning on the path through the stop node.
MATCH p=(a:Node {name: 'A'})-[:CONNECTED*]->(z:Node {name: 'Z'})
UNWIND range(1,length(p)) AS idx
WITH p, collect(CASE WHEN (nodes(p)[idx-1]).name = 'stop' THEN idx END) AS stops_found
RETURN nodes(p)[0..stops_found[0]]
Here is an APOC example. This example uses apoc.path.expand
. It findsthe A and Z nodes first and then it finds a collection of stopper nodes. It then passes these into apoc.path.expandConfig and follows CONNECTED
relationships and Node
labels until it reaches either a stopper node or Z.
MATCH (a:Node {name: 'A'}), (z:Node {name: 'Z'})
WITH a, z
MATCH (stop:Node {name: 'stop'})
WITH a, z, collect(stop) AS stoppers
CALL apoc.path.expandConfig(a, {relationshipFilter:'CONNECTED>', labelFilter:'+Node', terminatorNodes: stoppers + [z], uniqueness: 'NODE_GLOBAL'}) YIELD path
RETURN path
Here is another APOC example. This is similar, but instead of "stop" being an attribute value on a node it uses a termination filter on a Stop
label. It does not look for the end node Z but will continue on matching connections provided no Stop
label is encountered.
MATCH (a:Node {name: 'A'})
CALL apoc.path.expandConfig(a, {relationshipFilter:'CONNECTED>', labelFilter:'+Node|/Stop', uniqueness: 'NODE_GLOBAL'}) YIELD path
RETURN path
11-26-2019 03:30 PM
Here are a few queries to get you going on your solution.
This is the simplest one. Look for a path, p, that starts at 'A' and ends at a node with either 'Z' or 'stop'. Then return only the shortest of all of the matches if there are multiple. The theory here is that if the 'stop' is encountered first it will stop there.
MATCH p=(a:Node {name: 'A'}) - [:CONNECTED*] -> (end:Node)
WHERE end.name in ['stop','Z']
RETURN p
ORDER BY length(p)
LIMIT 1
Here is a another pure cypher example. This one finds the path from A..Z first and then looks for a stop node afterwards. If there is/are stop node(s) it collects them and then uses the first one to only return from the beginning on the path through the stop node.
MATCH p=(a:Node {name: 'A'})-[:CONNECTED*]->(z:Node {name: 'Z'})
UNWIND range(1,length(p)) AS idx
WITH p, collect(CASE WHEN (nodes(p)[idx-1]).name = 'stop' THEN idx END) AS stops_found
RETURN nodes(p)[0..stops_found[0]]
Here is an APOC example. This example uses apoc.path.expand
. It findsthe A and Z nodes first and then it finds a collection of stopper nodes. It then passes these into apoc.path.expandConfig and follows CONNECTED
relationships and Node
labels until it reaches either a stopper node or Z.
MATCH (a:Node {name: 'A'}), (z:Node {name: 'Z'})
WITH a, z
MATCH (stop:Node {name: 'stop'})
WITH a, z, collect(stop) AS stoppers
CALL apoc.path.expandConfig(a, {relationshipFilter:'CONNECTED>', labelFilter:'+Node', terminatorNodes: stoppers + [z], uniqueness: 'NODE_GLOBAL'}) YIELD path
RETURN path
Here is another APOC example. This is similar, but instead of "stop" being an attribute value on a node it uses a termination filter on a Stop
label. It does not look for the end node Z but will continue on matching connections provided no Stop
label is encountered.
MATCH (a:Node {name: 'A'})
CALL apoc.path.expandConfig(a, {relationshipFilter:'CONNECTED>', labelFilter:'+Node|/Stop', uniqueness: 'NODE_GLOBAL'}) YIELD path
RETURN path
11-26-2019 09:08 PM
Thank you daved for the solution and for considering different use-cases.
All the sessions of the conference are now available online