【问题标题】:natural order with a filter on MongoDB capped collection在 MongoDB 上限集合上使用过滤器的自然顺序
【发布时间】:2016-12-05 23:15:41
【问题描述】:

我有一个带有以下索引的 MongoDB 上限集合:

[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "events.messageIn"
    },
    {
        "v" : 1,
        "key" : {
            "uuid" : 1,
            "ts" : -1
        },
        "name" : "uuid_1_ts_-1",
        "ns" : "events.messageIn",
        "background" : true
    }
]

正如您可能推断的那样,这是事件数据的集合。因为时间戳总是在增加,所以订单{$natural: -1} 应该等同于订单{ts: -1}。我顺便在ts 上添加了一个索引,以便能够对时间片进行高效查询(例如db.messageIn.find({ts: {$gte: ISODate("2016-08-01")}})

但是,我(也许是天真地)期望db.messageIn.find({uuid: SOME_UUID}).sort({$natural: -1}) 会最有效地回答“给我 SOME_UUID 的最新消息”这个合乎逻辑的问题。事实上,该查询是一个集合扫描,比db.event.find({uuid: SOME_UUID}).sort({ts: -1}) 的计划慢几个数量级。

为什么会这样?推测性地,我假设这是因为 MongoDB 认为,一旦查看索引,它将无法提供自然顺序;结果,它回归到集合扫描。 MongoDB 有没有办法让这个查询更聪明?例如,用一本书的索引来类比:

uuid     ts                page
abcdef   2016-06-01T00:03  10
abcdef   2016-06-01T00:02  8
abcdef   2016-06-01T00:01  6
ghijkl   2016-06-01T00:03  9
mnopqr   2016-06-01T00:02  7
mnopqr   2016-06-01T00:01  5

通过uuid过滤后,您可以轻松按页排序;无需按顺序访问每个页面,检查其 uuid,如果匹配则生成页面。 MongoDB 的“页面”引用是否不可排序?很明显,我的心智模型在某处有所不足。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    根据我对the documentation 的理解,为了支持更高的插入吞吐量上限集合,请不要使用索引以插入顺序(或向后插入顺序)返回文档。因此,当执行db.messageIn.find({uuid: SOME_UUID}).sort({$natural: -1}) 时,每个文档都会被逐一检查以保留插入顺序并过滤匹配的文档。

    另一方面,db.event.find({uuid: SOME_UUID}).sort({ts: -1}) 更快,因为它使用“uuid_1_ts_-1”索引来匹配 uuid 和排序。在 MongoDB 中,排序操作可以通过根据索引中的顺序检索文档来获得排序顺序(documentation 描述的情况与您的情况非常相似)。

    顺便说一句,“uuid_1_ts_-1”不会用于像 db.messageIn.find({ts: {$gte: ISODate("2016-08-01")}}) 这样的查询,因为它是一个复合索引,对于复合索引,MongoDB 只能使用 the index prefixes 来支持查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      • 2016-05-16
      • 1970-01-01
      • 2013-06-08
      • 1970-01-01
      相关资源
      最近更新 更多