Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
02-07-2022 05:33 AM
Hello, I have the following path:
(a:Node)-[REL1]->(b:Node)-[REL1]->(c:Node)-[REL2]-(d:Node)-[REL1]->(e:Node)-[REL2]->(f:Node)
Now, REL1
and REL2
can be modelled either as 2 relationship types that can COEXIST
between 2 nodes or the same relationship type ( REL
) with different relationship properties. What is the most performant / efficient way to model and query the following scenario: - start from Node a
and find nodes c
and e
that are connected with REL2
with the next node ( d
and f
) in the path
Solved! Go to Solution.
02-07-2022 10:58 AM
Hi @magaton
This is the test data.
CREATE (:Node {name:'a'})-[:REL1]->(:Node {name:'b'})-[:REL1]->(:Node {name:'c'})-[:REL2]->(:Node {name:'d'})-[:REL1]->(:Node {name:'e'})-[:REL2]->(:Node {name:'f'})
How about this Cypher?
MATCH (:Node {name:'a'})-[:REL1|REL2*..10]->(n:Node)
WHERE EXISTS {
MATCH (n)-[:REL2]->(:Node)
}
RETURN n;
The Cypher is same as this old code.
MATCH (:Node {name:'a'})-[:REL1|REL2*..10]->(n:Node)
WHERE (n)-[:REL2]->(:Node)
RETURN n;
02-07-2022 10:58 AM
Hi @magaton
This is the test data.
CREATE (:Node {name:'a'})-[:REL1]->(:Node {name:'b'})-[:REL1]->(:Node {name:'c'})-[:REL2]->(:Node {name:'d'})-[:REL1]->(:Node {name:'e'})-[:REL2]->(:Node {name:'f'})
How about this Cypher?
MATCH (:Node {name:'a'})-[:REL1|REL2*..10]->(n:Node)
WHERE EXISTS {
MATCH (n)-[:REL2]->(:Node)
}
RETURN n;
The Cypher is same as this old code.
MATCH (:Node {name:'a'})-[:REL1|REL2*..10]->(n:Node)
WHERE (n)-[:REL2]->(:Node)
RETURN n;
02-07-2022 12:07 PM
Great, thank you!
I am not sure how it would work with relationship properties (single rel type REL) when one cannot use property filtering in WHERE EXISTS
02-07-2022 08:18 PM
I am having a difficult time understanding the requirements, but you can try something like this if you can't add more specific constraints to your pattern. The following allows you to specify relationship criteria that can occur anywhere along the path. Add multiple 'Any' clauses for each relationship criteria you want along the path. The example shows criteria having a mixture of property and relationship type criteria.
match p = (:Node {name:'a'})-[:REL1|REL2*]->(:Node {name:'f'})
with p, relationships(p) as relationships
where any(i in relationships where i.relationshipProperty = 'value' and i:REL1)
and any(i in relationships where i. i.relationshipProperty = 'value2' and i:REL2)
and any(i in relationships where i. i.relationshipProperty = 'value3')
return p
02-08-2022 03:38 AM
The accepted solution works when there are two types of relationships in the path: REL1
and REL2
I am looking for the solution in case there is a single relationship type: REL
and I need to find nodes in the path, which have OUTGOING
relationship of type REL
with property rank
> rank on the first relationship in the path:
Here is the dataset:
CREATE (:Node {name:'a'})-[:REL{rank:1}]->(:Node {name:'b'})-[:REL{rank:1}]->(:Node {name:'c'})-[:REL{rank:2}]->(:Node {name:'d'})-[:REL{rank:1}]->(:Node {name:'e'})-[:REL{rank:2}]->(:Node {name:'root'})
The query should be able to find nodes c
and e
because they have outgoing REL
with rank=2
that is greater than 1 which is set on the REL
from Node a
.
I have tried with predicate functions (a bit modified) you provided in your answer, but that does not seem to work.
Hope this explains the problem better now.
02-08-2022 12:30 PM
I think I understand. Try this:
match p=(:Node{name:'a'})-[:REL*]->(:Node{name:'root'})
with relationships(p) as relationships
with relationships[0] as first, tail(relationships) as remaining
with [i in remaining where i.rank > first.rank] as filtered
unwind filtered as relationship
return startNode(relationship) as result
All the sessions of the conference are now available online