Reputation: 1297
This is sort of related to this question, but not quite the same: Performing a MATCH on all nodes on a path
Like in the previous question I have a similar setup:
(a)-->(b)-->(c)-->(d)
^ ^ ^ ^
|r |r |r |r
(aa) (bb) (cc) (dd)
Example Create (See Console http://console.neo4j.org/r/vx99q):
CREATE
(a {name:'a'}),
(b {name:'b'}),
(c {name:'c'}),
(d {name:'d'}),
(aa {name:'aa'}),
(bb {name:'bb'}),
(cc {name:'cc'}),
(dd {name:'dd'}),
a-[:rel1]->b,
b-[:rel1]->c,
c-[:rel1]->d,
a-[:r]->aa,
b-[:r]->bb,
c-[:r]->cc,
d-[:r]->dd;
Let's say I have a
as 7 and d
as 4. I would get the path like this:
START a=node(7), d=node(4)
MATCH path = a-[:rel1*]->d
RETURN path
What I want is aa, bb, cc, and dd.
I'm stumped.
Upvotes: 0
Views: 336
Reputation: 1297
Well it took a bit of wrapping my head around this, but I figured it out.
START n=node(*), a=node(1), z=node(4)
MATCH path = a-[:rel1*]->z
WITH n, path
MATCH n-[:r]->o
WHERE n IN path
RETURN o
Though it does seem slow, I imagine that there is probably a better way to do it.
Output:
o
(5 {name:"aa"})
(6 {name:"bb"})
(7 {name:"cc"})
(8 {name:"dd"})
Edit: yhw42 mentioned that the query could run faster if modified like so:
START a=node(1), z=node(4)
MATCH path = a-[:rel1*]->z
WITH path
MATCH n-[:r]->o
WHERE n IN path
RETURN o
In the sample, it did. My way was:
Query Results
+--------------------+
| o |
+--------------------+
| Node[5]{name:"aa"} |
| Node[6]{name:"bb"} |
| Node[7]{name:"cc"} |
| Node[8]{name:"dd"} |
+--------------------+
4 rows
344 ms
Execution Plan
ColumnFilter(symKeys=["n", "path", "o", " UNNAMED88"], returnItemNames=["o"], _rows=4, _db_hits=0)
PatternMatch(g="(n)-[' UNNAMED88']-(o)", _rows=4, _db_hits=0)
Filter(pred="any(-_-INNER-_- in path where n == -_-INNER-_-)", _rows=4, _db_hits=0)
ColumnFilter(symKeys=["path", "n", "a", " UNNAMED53", "z"], returnItemNames=["n", "path"], _rows=9, _db_hits=0)
ExtractPath(name="path", patterns=[" UNNAMED53=a-[:rel1*]->z"], _rows=9, _db_hits=0)
PatternMatch(g="(a)-[' UNNAMED53']-(z)", _rows=9, _db_hits=0)
NodeById(name="Literal(List(4))", identifier="z", _rows=9, _db_hits=9)
NodeById(name="Literal(List(1))", identifier="a", _rows=9, _db_hits=9)
AllNodes(identifier="n", _rows=9, _db_hits=9)
His way was:
Query Results
+--------------------+
| o |
+--------------------+
| Node[5]{name:"aa"} |
| Node[6]{name:"bb"} |
| Node[7]{name:"cc"} |
| Node[8]{name:"dd"} |
+--------------------+
4 rows
174 ms
Execution Plan
ColumnFilter(symKeys=["path", "n", "o", " UNNAMED74"], returnItemNames=["o"], _rows=4, _db_hits=0)
PatternMatch(g="(n)-[' UNNAMED74']-(o)", _rows=4, _db_hits=0)
Filter(pred="any(-_-INNER-_- in path where n == -_-INNER-_-)", _rows=4, _db_hits=0)
AllNodes(identifier="n", _rows=9, _db_hits=9)
ColumnFilter(symKeys=["a", "z", " UNNAMED42", "path"], returnItemNames=["path"], _rows=1, _db_hits=0)
ExtractPath(name="path", patterns=[" UNNAMED42=a-[:rel1*]->z"], _rows=1, _db_hits=0)
PatternMatch(g="(a)-[' UNNAMED42']-(z)", _rows=1, _db_hits=0)
NodeById(name="Literal(List(4))", identifier="z", _rows=1, _db_hits=1)
NodeById(name="Literal(List(1))", identifier="a", _rows=1, _db_hits=1)
Upvotes: 1