【问题标题】:Efficiently find the most recent filtered document in MongoDB collection using datetime field使用 datetime 字段有效地查找 MongoDB 集合中最近过滤的文档
【发布时间】:2021-12-31 00:07:10
【问题描述】:

我有大量包含日期时间字段的文档,我需要检索任何给定查询列表的最新文档。

样本数据:

[
  {"_id": "42.abc",
   "ts_utc": "2019-05-27T23:43:16.963Z"},
  {"_id": "42.def",
   "ts_utc": "2019-05-27T23:43:17.055Z"},
  {"_id": "69.abc",
   "ts_utc": "2019-05-27T23:43:17.147Z"},
  {"_id": "69.def",
   "ts_utc": "2019-05-27T23:44:02.427Z"}
]

基本上,我需要获取“42”组的最新记录以及“69”组的最新记录。使用上面的示例数据,“42”组的期望结果将是文档“42.def”。

我目前的解决方案是一次查询一个组(使用 PyMongo 循环),按 ts_utc 字段排序,并将其限制为一个,但这真的很慢。 p>

// Requires official MongoShell 3.6+
db = db.getSiblingDB("someDB");
db.getCollection("collectionName").find(
    { 
        "_id" : /^42\..*/
    }
).sort(
    { 
        "ts_utc" : -1.0
    }
).limit(1);

有没有更快的方法来获得我想要的结果?

【问题讨论】:

  • 向文档添加属性,例如“group”:“42”(或 69)。该道具和 ts_utc 道具上的索引。

标签: mongodb mongodb-query


【解决方案1】:

假设您的所有文档都具有上面显示的格式,您可以将 id 拆分为两部分(使用点字符)并使用聚合来查找每个第一个数组(数字)元素的最大元素。

这样您就可以一次性完成,而不是按每个组进行迭代。

db.foo.aggregate([
    { $project: { id_parts : { $split: ["$_id", "."] }, ts_utc : 1 }},
    { $group: {"_id" : { $arrayElemAt: [ "$id_parts", 0 ] }, max : {$max: "$ts_utc"}}}
])

【讨论】:

    【解决方案2】:

    正如评论中提到的@danh,您可以做的最好的方法可能是添加一个辅助字段来指示分组。您可以进一步索引辅助字段以提高性能。

    这是一种派生字段并获得每个分组的最新结果的特别方法:

    db.collection.aggregate([
      {
        "$addFields": {
          "group": {
            "$arrayElemAt": [
              {
                "$split": [
                  "$_id",
                  "."
                ]
              },
              0
            ]
          }
        }
      },
      {
        $sort: {
          ts_utc: -1
        }
      },
      {
        "$group": {
          "_id": "$group",
          "doc": {
            "$first": "$$ROOT"
          }
        }
      },
      {
        "$replaceRoot": {
          "newRoot": "$doc"
        }
      }
    ])
    

    这里是Mongo playground 供您参考。

    【讨论】:

      猜你喜欢
      • 2012-03-18
      • 2017-08-12
      • 1970-01-01
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      • 2018-04-21
      相关资源
      最近更新 更多