【问题标题】:MongoDB: using limit and skip on complex sort order in either directionMongoDB:在任一方向上使用限制和跳过复杂的排序顺序
【发布时间】:2013-12-13 01:41:08
【问题描述】:

我有一个使用多个字段的复杂排序顺序。 “条目对象”是由查询定义的第一批中的第一项。我正在尝试创建一个无限滚动条,其中条目项目显示在顶部 - 向下滚动按预期工作并向上滚动条目项目之前的显示项目。

对像“用户名”这样的唯一字段使用简单排序非常简单,但在我的情况下,排序至少需要三个字段才能产生唯一排序。

颠倒排序顺序也不成问题。

问题是如何定义条目对象并使用跳过和限制在排序集合中获取条目对象之后和之前的项目。 afaik 不允许 skip 为负值。

使用 mongoid 和 Rails 来定义排序:

scope :rating_watchable, order_by(avg_rating: :desc, release_date: :desc, title: :asc)

从下面返回的第一个对象是位置 0 的“入口对象”:

Object.rating_watchable.where(:avg_rating.gte => 3).skip(0).limit(BATCH_SIZE)

最后一个查询正确返回对象,如果我颠倒排序顺序,我可以按正确顺序获取对象,但我想不出如何使用相对“where”子句定义相同的条目对象。我需要这个来让跳过/限制以相反的顺序正常工作。

如果有这样的否定跳过当然会很好:

Object.rating_watchable.where(:avg_rating.gte => 3).skip( -BATCH_SIZE * batch_num ).limit(BATCH_SIZE)

也许我错过了一些更好的方法来做到这一点?

【问题讨论】:

    标签: mongodb mongoid mongoid3


    【解决方案1】:

    潜在的问题是您有一个排序顺序,并且您试图在排序顺序中找到一个对象(条目对象)的索引。根据定义,您必须从排序中获取结果才能在排序顺序中获取条目对象的索引。所以...

    1) 获取入口对象的_id,然后 2)从排序中获取_id,然后 3)在排序_id的中找到入口对象_id的索引

    鉴于上述情况,您现在可以使用跳过和限制来显示从条目对象开始的初始页面,并计算适当的跳过和限制值以按排序顺序向前或向后移动一页或多页。

    MongoDB 允许您从文档中“投影”选定的顶级字段,使用此功能来选择_id,这样您就不必为完整的排序结果反序列化整个文档支付开销,请参阅http://docs.mongodb.org/manual/tutorial/project-fields-from-query-results/ - 在 Mongoid 中,这是使用 Criteria#pluck 进行查询,在 Moped 中这是 #select,请参阅 http://mongoid.org/en/mongoid/docs/querying.html

    希望这会有所帮助。

    【讨论】:

    • 谢谢,我会看的。我最终做了一些不同的事情,导致了一些非常难看的冗余代码,但确实有效:如果我定义了一个正向和反向排序顺序,那么当我指定一个 .where 包含条目对象(在正向)和排除(反向)。我还必须定义索引以支持两种排序顺序。在实践中,这并不太难,它是一个 .gte 用于一个订单而 .lt 在另一个订单的 .where,这必须为每个订单字段完成。不过,您的回答可能会导致代码更简单,所以我会研究一下。
    猜你喜欢
    • 2017-12-18
    • 1970-01-01
    • 2016-03-07
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    相关资源
    最近更新 更多