0

我目前正在使用具有 50000 个节点和 200 万个关系的 neo4j 数据库来执行密码MATCH查询,如下所示:

start startnode = node(42660), endnode = node(30561)
match startnode-[r*1..3]->endnode
return r;

这个查询本身提供了 443 行,但我只希望 Cypher 找到 5 个匹配项并只返回那些。请允许我澄清一下:我不仅希望 Cypher 只返回 5 个结果,我还希望 cypher 在找到 5 个结果后停止查询。我不希望 Cypher 获得所有 443 个结果。

目前可以使用该LIMIT子句吗?还是会LIMIT等待找到所有 443 个结果,然后只返回前 5 个?

编辑LIMIT对于这样的复杂查询,该子句是否只会找到前几个结果?

start graphnode = node(1), startnode = node(42660), endnode = node(30561)
match startnode<-[:CONTAINS]-graphnode-[:CONTAINS]->endnode
with startnode, endnode
match startnode-[r1*1..1]->endnode
with r1, startnode, endnode
limit 30
match startnode-[r2*2..2]->endnode
with r1, r2, startnode, endnode
limit 30
match startnode-[r3*3..3]->endnode
with r1, r2, r3, startnode, endnode
limit 30
return r1,r2,r3;

这是profile查询的:

==> ColumnFilter(symKeys=["  UNNAMED216", "endnode", "r1", "startnode", "r2", "r3"],   returnItemNames=["r1", "r2", "r3"], _rows=30, _db_hits=0)
==> Slice(limit="Literal(30)", _rows=30, _db_hits=0)
==>   PatternMatch(g="(startnode)-['  UNNAMED216']-(endnode)", _rows=30, _db_hits=0)
==>     ColumnFilter(symKeys=["endnode", "  UNNAMED140", "r1", "startnode", "r2"], returnItemNames=["r1", "r2", "startnode", "endnode"], _rows=1, _db_hits=0)
==>       Slice(limit="Literal(30)", _rows=1, _db_hits=0)
==>         PatternMatch(g="(startnode)-['  UNNAMED140']-(endnode)", _rows=1, _db_hits=0)
==>           ColumnFilter(symKeys=["startnode", "endnode", "  UNNAMED68", "r1"], returnItemNames=["r1", "startnode", "endnode"], _rows=1, _db_hits=0)
==>             Slice(limit="Literal(30)", _rows=1, _db_hits=0)
==>               PatternMatch(g="(startnode)-['  UNNAMED68']-(endnode)", _rows=1, _db_hits=0)
==>                 NodeById(name="Literal(List(30561))", identifier="endnode", _rows=1, _db_hits=1)
==>                   NodeById(name="Literal(List(42660))", identifier="startnode", _rows=1, _db_hits=1)
4

1 回答 1

2

这取决于您在做什么,但是在这种情况下,如果您要添加limit 5after return,它将能够懒惰地返回并跳过其余的比赛。如果您想要排序或聚合,它就无法为您做到这一点。如果您发现这不是行为,请在 github 上将其报告为问题(以及您正在使用的版本等)

更新新查询

start graphnode = node(1), startnode = node(42660), endnode = node(30561)
match startnode<-[:CONTAINS]-graphnode-[:CONTAINS]->endnode // do you need this, or is it always going to be true?
with startnode, endnode                                     // ditto. take it out if it doesn't need to be here.
match startnode-[r1*1..1]->endnode // this can probably be simplified to just startnode-[r1]->endnode
with r1, startnode, endnode 
limit 30 // limit to the first 30 it finds in the previous match (this should be lazy)
match startnode-[r2*2..2]->endnode // finds 2 levels deep
with r1, r2, startnode, endnode
limit 30 // limit to the first 30 it finds in the previous match (this should be lazy)
match startnode-[r3*3..3]->endnode
return r1,r2,r3 // the last with you had was extraneous, return will function the same way
limit 30; 

所以,我假设你在问一个问题,因为这个查询很慢。我可以问你为什么以这种方式分解它,而不是仅仅startnode-[r*1..3]->endnode, 和limit 30?你真的需要第一次匹配/匹配,还是不需要检查?你能提供输出PROFILE吗?

于 2013-07-11T19:26:28.587 回答