2013-07-26 143 views
0

这有点与此相关的问题,但不完全一样:Performing a MATCH on all nodes on a pathNeo4j的充分利用节点的节点的路径

像前面的问题,我有一个类似的设置:

(a)-->(b)-->(c)-->(d) 
^ ^ ^ ^
|r |r |r |r 
(aa) (bb) (cc) (dd) 

例创建(见控制台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; 

比方说,我有a第7和第d为4。我会得到在p像这样:

START a=node(7), d=node(4) 
MATCH path = a-[:rel1*]->d 
RETURN path 

我想要的是aa,bb,cc和dd。

我很难过。

回答

1

好吧,我花了一些时间来围绕这个问题,但我明白了。

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 

虽然它看起来很慢,但我想可能有更好的方法来做到这一点。

输出:

o 
(5 {name:"aa"}) 
(6 {name:"bb"}) 
(7 {name:"cc"}) 
(8 {name:"dd"}) 

编辑: yhw42提到,如果修改,像这样的查询可以运行得更快:

START a=node(1), z=node(4) 
MATCH path = a-[:rel1*]->z 
WITH path 
MATCH n-[:r]->o 
WHERE n IN path 
RETURN o 

在样本,它没有。我的办法是:

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) 

他的做法是:

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) 
+1

你应该能够删除'N =从离开ñ只有在START子句和'从N'节点(*)'第二个MATCH和WHERE。这是否有速度差异? – yhw42

+0

我的方式是344ms,你的方式是174ms。超小型数据集,所以我认为它很重要。 – LameCoder