0
votes

I am having trouble creating an appropriate Cypher query. I would like to return the sub-graph of all edges & nodes within a certain distance of a topic node. This could easily be done with something like:

START (topic: attribute)-[rel: describedBy*0..4]-(node: attribute
WHERE id(topic) IN [37, 38] 
RETURN rel;

The problem is I want to remove paths where any of the nodes in the path (other than the end node) have the property "key" with either the value "enrichment" or "classification".

I've tried removing paths using:

MATCH path=(topic: attribute)-[rel: describedBy|influences*0..4]-(intermediate: attribute)-[rel: describedBy|influences*0..4]-(node: attribute)
WHERE id(topic) IN [37,38] AND NOT intermediate in [x IN nodes(path) WHERE x.key IN ['enrichment', 'classification'] | x] and length(path) < 5
RETURN rel;

I've tried filtering at each potential distance in the path:

MATCH (topic: attribute)-[rel:describedBy|influences]-(node: attribute)
WHERE id(topic) IN [37,38]
RETURN rel as rels
UNION
MATCH path=(topic: attribute)-[rel: describedBy|influences*1]-(intermediate: attribute)-[rel: describedBy|influences*1..3]-(node: attribute)
WHERE id(topic) IN [37,38] AND NOT intermediate.key in ['enrichment', 'classification'] and length(path) < 5
RETURN rel as rels
UNION
MATCH path=(topic: attribute)-[rel: describedBy|influences*2]-(intermediate: attribute)-[rel: describedBy|influences*1..2]-(node: attribute)
WHERE id(topic) IN [37,38] AND NOT intermediate.key in ['enrichment', 'classification'] and length(path) < 5
RETURN rel as rels
UNION
MATCH path=(topic: attribute)-[rel: describedBy|influences*3]-(intermediate: attribute)-[rel: describedBy|influences*1..1]-(node: attribute)
WHERE id(topic) IN [37,38] AND NOT intermediate.key in ['enrichment', 'classification'] and length(path) < 5
RETURN rel as rels;

I was hoping the 2nd match would stop paths that go (37)-[rel]-(32)-[rel*0..3]-(), where 32 has 'key':'enrichment', however it does not.

Does anyone have any suggestions how I could formulate a query to stop following a path when it reaches a node with a specific key:value pair?

Thank you for the help.

1
As an aside, I'd also like to replace the node.key IN [value list] match with some type of degree(node) < value match, if that's possible.Gabe

1 Answers

1
votes

I think this does what I want:

MATCH path=(topic: attribute)-[rel:describedBy|influences]-(node: attribute)
WHERE id(topic) IN [128204]
RETURN DISTINCT extract(r IN rels(path) | r)
UNION
MATCH path=(topic: attribute)-[rel1: describedBy|influences]-(intermediate: attribute)-[rel2: describedBy|influences]-(node: attribute)
WHERE id(topic) IN [128204] AND NOT intermediate.key in ['enrichment', 'classification'] and length(path) < 5
RETURN DISTINCT extract(r IN rels(path) | r)