【问题标题】:Limiting Cypher queries限制 Cypher 查询
【发布时间】:2013-07-11 18:52:45
【问题描述】:

我目前正在使用具有 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)

【问题讨论】:

    标签: optimization neo4j cypher


    【解决方案1】:

    这取决于你在做什么,但在这种情况下,如果你在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]-&gt;endnodelimit 30?你真的需要第一次匹配/匹配,还是不需要检查?可以提供PROFILE的输出吗?

    【讨论】:

    • 我不确定这是否是正常行为。我用复杂的查询start graphnode = node(1), startnode= node(42660), endnode = node(30561) match startnode&lt;-[:CONTAINS]-graphnode-[:CONTAINS]-&gt;endnode with startnode, endnode match startnode-[r1*1..1]-&gt;endnode with r1, startnode, endnode limit 30 match startnode-[r2*2..2]-&gt;endnode with r1, r2, startnode, endnode limit 30 match startnode-[r3*3..3]-&gt;endnode with r1, r2, r3, startnode, endnode limit 30 return r1,r2,r3; 尝试了这个。尽管有种种限制,但还是花了一分钟才得到结果。
    • 为了便于阅读,我已将这个复杂的查询放在我的问题中。
    • 我正在分解查询,因为我稍后打算为限制输入参数。例如,我希望能够将整个路径列表的限制设置为 30,并减少每一层的限制。 (如果 1..1 产生 1 个路径,那么我希望 2..2 的限制为 29)。另外,我已经删除了第一个匹配/与;该检查是不必要的。但是,我仍然遇到性能问题。我会尽快添加profile 输出。
    • 我还尝试将查询扩展到4..4,但最终没有结果,可能是 GC 转储。这是我在日志中发现的:GC Monitor: Application threads blocked for an additional 14813ms [total block time: 182.589s]
    • 如果您需要有关扩展的帮助,请发布新问题或在 twitter @wefreema 上给我留言。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 2015-11-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多