2013-07-11 71 views
0

我目前使用的有50000个节点和200万间关系的Neo4j的数据库进行暗号MATCH查询,像下面这样:限制的Cypher查询

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

此查询本身提供了443行,但我只想要Cypher找到5个匹配并仅返回这些匹配。请允许我澄清:我不仅仅希望Cypher只返回5个结果,我还希望密码一旦找到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) 

回答

2

这取决于你在做什么,但在这种情况下,如果你是return后添加limit 5,就能够懒洋洋地返回并跳过其余的比赛。如果你想要排序或聚合,它将无法为你做到这一点。如果你觉得这不是问题,请将其报告为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]->endnodelimit 30?你真的需要第一场比赛吗?或者这种检查是不必要的?你能提供PROFILE的输出吗?

+0

我不确定这是否是正常行为。我尝试了一个复杂的查询'start graphnode = node(1),startnode = node(42660),endnode = node(30561)match startnode < - [:CONTAINS] -graphnode - [:CONTAINS] - > endnode with startnode ,endnode匹配startnode- [r1 * 1..1] - > endnode与r1,startnode,endnode限制30匹配startnode- [r2 * 2..2] - > endnode与r1,r2,startnode,endnode限制30匹配startnode - [r3 * 3..3] - > end1与r1,r2,r3,startnode,endnode限制30返回r1,r2,r3;'。尽管有所有限制,但花费了一分钟的时间才得到结果。 –

+0

我已经把这个复杂的查询放在我的问题中,以方便阅读。 –

+1

更新为新的查询 –