I have nodes between which there may be links.
Each node has a field, which I have now called a subject.
My task would be to be able to select the complete paths where the nodes following each other on the path have a certain subject.
Previously I used mongo dbt, there I used the $setIsSubset function to search for this.
Can someone give me a tutorial on how I can implement this in cypher .
MATCH p=(start:Annotation)-[:connection*1..100]->(end:Annotation)
WITH nodes(p) as path
WHERE ANY(node in path WHERE node.SubjectId ="5f02e8254850751ffc044c8a" OR node.SubjectId ="6493f28567d762570722e613")
RETURN path
LIMIT 150
I tried something like this, but this is obviously not a good solution.
There's a whole documentation about the new Quantified Patter Matching syntax here.
In this case, you can start trying something like:
MATCH p=(start:Annotation)((a)-[:connection]->(b) WHERE a.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"] and b.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"]){1,100}(end:Annotation)
RETURN p //edited
LIMIT 150
You may like to add some conditions on your start and end node in order to avoid calculating the same thing multiple times tho.
Hi @bennu_neo
First of all, thanks for the help, and the reply.
Maybe I explained it wrong, but this is not a good solution.
this will return only the two nodes for which the condition is met.
However, I want to get the full path back.
find the graph where the subjects of the successive nodes are s1 and s2.
so this is true for the first, not for the second.
and I would like to get this result back:
a1(s0) - > a2(s1) -> a3(s2) -> a4(s3)
MATCH p=(start:Annotation)-[:connection*1..100]->(end:Annotation)
RETURN p
ORDER BY length(p) DESC
LIMIT 1
within this graph there are two nodes where the two ids follow each other: 64a592c5868c0d0007218fef, 64a592c5868c0d0007218fee.
so if I substitute this into your query, I want to see the same result as the longest path query above, i.e. the full path.
instead I get the result shown in the picture:
Hello @bennu_neo
I think this is still not the expected result
For this query:
MATCH p =()(()-[:connection]->()){,100}(b)-[:connection]->(c) (()-[:connection]->()){,100}()
WHERE b.SubjectId ='5f02e8254850751ffc044c8a'
AND c.SubjectId ='6493f28567d762570722e613'
RETURN p LIMIT 100
MATCH p=(start:Annotation)((a)-[:connection]->(b)
WHERE a.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"]
and b.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"]){1,100}(end:Annotation)
RETURN p
LIMIT 150
MATCH p =()(()-[:connection]->()){,100}(b)-[:connection]->(c) (()-[:connection]->()){,100}()
WHERE b.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"]
and c.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"]
RETURN p LIMIT 100
And what happens if I want to include exactly these nodes anywhere on the graph ?
What operator can be used instead of IN ?
So now if I specify that I'm looking for 3 subjects, it will return subjects where, for example, 2 of the 3 follow each other, but the 3rd is not even listed.
The IN operator has nothing to do with position of the nodes but it only enforce the desired condition.
MATCH p =()(()-[:connection]->()){,100}(b)-[:connection*]->(c)(()-[:connection]->()){,100}()
WHERE b.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"]
and c.SubjectId in ["5f02e8254850751ffc044c8a", "6493f28567d762570722e613"]
RETURN p
This one should work for distances between your 2 targets bigger than 1. However, for more intricate scenarios, as always, I may say: "It depends". You can always fallback into path predicates as ANY but be aware those are not enforces runtime but are post traversal filters, so memory can grow a lot before noticing that many of the calculated paths are not valid.