Noor
Noor

Reputation: 20150

Cypher constraint on direction of successive relationship

short version: I need to get a path that can contain different relationships in different directions. However, I have a constraint on my path where if it contains successive relationships of a particular type, then both relationship must be in the same direction.

long version: I am using the query below to get a path between two nodes:

MATCH p=shortestPath((n:Class { code: '1' })-[r*]-(m:Class { code: '4'})) WHERE NONE(x IN NODES(p) WHERE 'Ontology' in labels(x)) return p

The query correctly returns me a shortest path between the two nodes. However I need to further constraint this query so that it returns only path where successive relationship of a particular type are in the same direction.

For example, suppose the relationship -a-> need to be in the same direction, it should not return (1)-a->(2)<-a-(3)-b->(4) but can return (1)-a->(6)-a->(3)-b->(7)<-c-(5)<-d-(6)-e->(4) or (3)-b->(7)<-c-(4) .

The above examples were just a simplification of my real data. In my real use case, I need to find a shortest path between a node with IRI http://elite.polito.it/ontologies/dogont.owl#Actuator and another node with IRI http://elite.polito.it/ontologies/dogont.owl#StateValue. The query below is a specific query that encodes the path I need and it returns a path, that is the path exist. I need to make it more generic using shortestpath.

MATCH p=(n:Class {iri: 'http://elite.polito.it/ontologies/dogont.owl#Actuator'})-->(a:Class)<--(b:ObjectProperty{iri:'http://elite.polito.it/ontologies/dogont.owl#hasState'})-->(c:Class{iri:'http://elite.polito.it/ontologies/dogont.owl#State'})<--(d:Class{iri:'http://elite.polito.it/ontologies/dogont.owl#hasStateValue'})-->(e:Class{iri:'http://elite.polito.it/ontologies/dogont.owl#StateValue'}) return p

Is this possible with cypher ?

Upvotes: 0

Views: 113

Answers (1)

cybersam
cybersam

Reputation: 67009

This query should work if you want to capture paths that are consistent in either direction (but it has to invoke shortestPath() twice):

MATCH (n:Class {code: '1'}), (m:Class {iri: '4'})
OPTIONAL MATCH p1=shortestPath((n)-[*]->(m))
WHERE NONE(x IN NODES(p1) WHERE 'Ontology' in labels(x))
OPTIONAL MATCH p2=shortestPath((n)<-[*]-(m))
WHERE NONE(y IN NODES(p2) WHERE 'Ontology' in labels(y))
RETURN p1, p2

p1 and/or p2 will be null if there is no consistently rightward or leftward path, respectively.

However, if you know that you want a specific direction (say, rightward), then this should work:

MATCH p=shortestPath((:Class {code: '1'})-[*]->(:Class {iri: '4'}))
WHERE NONE(x IN NODES(p) WHERE 'Ontology' in labels(x))
RETURN p

Upvotes: 1

Related Questions