【问题标题】:Find all documents within last n days查找过去 n 天内的所有文档
【发布时间】:2021-12-05 19:12:39
【问题描述】:

我的daily 收藏有如下文档:

..
{ "date" : ISODate("2013-01-03T00:00:00Z"), "vid" : "ED", "san" : 7046.25, "izm" : 1243.96 }
{ "date" : ISODate("2013-01-03T00:00:00Z"), "vid" : "UA", "san" : 0, "izm" : 0 }
{ "date" : ISODate("2013-01-03T00:00:00Z"), "vid" : "PAL", "san" : 0, "izm" : 169.9 }
{ "date" : ISODate("2013-01-03T00:00:00Z"), "vid" : "PAL", "san" : 0, "izm" : 0 }
{ "date" : ISODate("2013-01-03T00:00:00Z"), "vid" : "CTA_TR", "san" : 0, "izm" : 0 }
{ "date" : ISODate("2013-01-04T00:00:00Z"), "vid" : "CAD", "san" : 0, "izm" : 169.9 }
{ "date" : ISODate("2013-01-04T00:00:00Z"), "vid" : "INT", "san" : 0, "izm" : 169.9 }
...

我离开了 _id 字段以节省空间。 我的任务是“获取过去 15 天内的所有文件”。如您所见,我需要以某种方式:

  1. 获取 15 个唯一日期。最新的应该作为集合中的最新文档(我的意思是今天的日期不是必需的,它只是基于 date 字段的集合中的最新文档)和最旧的文档。 . 好吧,也许没有必要严格定义查询中最旧的一天,我需要的是从最新一天开始的某种 top15,如果你知道我的意思的话。就像 15 独特的天。
  2. db.daily.find() 在 15 天范围内具有 date 字段的所有文档。

结果,我应该会在 15 天内看到所有文档,从最新的集合开始。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    我刚刚针对您的数据样本测试了以下查询,它运行良好:

    db.datecol.find(
    {
        "date": 
        {
            $gte: new Date((new Date().getTime() - (15 * 24 * 60 * 60 * 1000)))
        }
    }
    ).sort({ "date": -1 })
    

    【讨论】:

    • 好极了,不知道你可以在 mongoDB 语句中创建 vars
    • 如果您选择使用 moment 框架,那么您可以使用以下命令创建 Date 实例:moment().subtract(15, 'days').toDate()
    • @EdwardCorrigall 非常感谢您在瞬间展示这一点。
    • ? 与答案中提出的解决方案相比,使用硬编码日期(即$gte: new Date(2021,7,7)显着性能更高。
    【解决方案2】:

    Mongo 5 开始,这是$dateSubtract 运算符的一个很好的用例:

    // { date: ISODate("2021-12-05") }
    // { date: ISODate("2021-12-02") }
    // { date: ISODate("2021-12-02") }
    // { date: ISODate("2021-11-28") } <= older than 5 days
    db.collection.aggregate([
      { $match: {
        $expr: {
          $gt: [
            "$date",
            { $dateSubtract: { startDate: "$$NOW", unit: "day", amount: 5 } }
          ]
        }
      }}
    ])
    // { date: ISODate("2021-12-05") }
    // { date: ISODate("2021-12-02") }
    // { date: ISODate("2021-12-02") }
    

    使用$dateSubtract,我们通过从当前日期$$NOW (startDate) 中减去5 (amount) "days" (unit) 来创建保存文档的最旧日期.

    您显然可以添加一个$sort 阶段来按日期对文档进行排序。

    【讨论】:

    • 完美答案。
    【解决方案3】:

    您需要运行distinct 命令来获取所有唯一日期。下面是示例。 “values”数组包含集合的所有唯一日期,您需要从中检索客户端最近的 15 天

    db.runCommand ( { distinct: 'datecol', key: 'date' } )
    {
        "values" : [
           ISODate("2013-01-03T00:00:00Z"),
           ISODate("2013-01-04T00:00:00Z")
        ],
        "stats" : {
           "n" : 2,
           "nscanned" : 2,
           "nscannedObjects" : 2,
           "timems" : 0,
           "cursor" : "BasicCursor"
        },
        "ok" : 1
    }
    

    然后,您使用$in 运算符与步骤 1 中最近的 15 个日期。下面是一个示例,用于查找属于上述两个日期之一的所有文档。

    db.datecol.find({
      "date":{
         "$in":[
            new ISODate("2013-01-03T00:00:00Z"), 
            new ISODate("2013-01-04T00:00:00Z")
          ]
      }
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 2012-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      相关资源
      最近更新 更多