首页 > 解决方案 > MongoDB:使用_id计算过去X天内每天创建的文档

问题描述

我希望在我的网站上收集有关用户的注册统计信息——过去 X 天通过 mongo shell 的注册计数。结果可能类似于:

Dec 7, 2019: 100
Dec 6, 2019: 150
Dec 5, 2019: 150
...

这些文件没有任何created_at属性,但是_id我相信有一个属性可以用来实现这个目标?

如果这可以帮助更清楚,那么 MySQL 中的等价物将类似于SELECT count(id) FROM Users WHERE created_at > timestamp_X_days_ago GROUP BY created_at ORDER BY DESC created_at

集合的名称是Users

我尝试了很多查询,我认为最接近的一个是db.Users.find({ "_id" : {$lt: new Date(), $gte: new Date(new Date().setDate(new Date().getDate()-1))}}).count(),如果_id我知道如何在_id.

蒙戈 3.6

标签: mongodbmongodb-queryaggregation-framework

解决方案


假设该_id字段的类型为ObjectId,以下查询按天按降序打印计数。

初始匹配阶段将按“过去 X 天”过滤文档。例如,要仅处理从今天开始过去 10 天的文档,请past_x_days以毫秒为单位获取并在查询中使用它:

var past_x_days = 10 * 86400000; // where 86400000 is millis per day (24*60*60*1000)

db.test.aggregate( [
  { 
      $match: { 
          $expr: { 
              $gt: [ { $toDate: "$_id" },  { $toDate: { $subtract: [ ISODate(), past_x_days ] } } ]  
          } 
      } 
  },
  { 
      $group: { 
          _id: { dateYMD: { 
             $dateFromParts : {
                 year: { $year: "$_id" }, 
                 month: { $month: "$_id" }, 
                 day: { $dayOfMonth: "$_id" }
             }
         } }, 
         count: { $sum: 1 } 
       } 
  },
  { 
      $sort: { "_id.dateYMD" : -1 } 
  },
  { 
      $project: { 
          _id: 0, 
          count: 1, 
          dateDMY: { $dateToString: { date: "$_id.dateYMD", format: "%d-%m-%Y" } } 
      } 
  }
] )

输出将如下所示:

{ "count" : 2, "dateDMY" : "09-12-2019" }
{ "count" : 3, "dateDMY" : "01-12-2019" }



注意:上述查询适用于 MongoDB 4.0 版。查询已修改为使用 3.6 版:

db.test.aggregate( [
  { 
      $addFields: { 
          oid_date: { $dateToParts: { date: "$_id" } }, 
          dt_diff: { $subtract: [ ISODate(), past_x_days ] }  
      }
  },
  { 
      $addFields: { 
          oid_dt_ymd: { 
              $dateFromParts: { 
                  year : "$oid_date.year", 
                  month : "$oid_date.month", 
                  day: "$oid_date.day" 
              } 
          }
      }
  },
  { 
      $match: { 
          $expr: { 
              $gt: [ "$oid_dt_ymd",  "$dt_diff"  ]  
          } 
      } 
  },
  { 
      $group: { 
          _id: "$oid_dt_ymd", 
          count: { $sum: 1 } 
       } 
  },
  { 
      $sort: { "_id" : -1 } 
  },
  { 
      $project: { 
          _id: 0, 
          count: 1, 
          dateDMY: { $dateToString: { date: "$_id", format: "%d-%m-%Y" } } 
      } 
  }
])

以下是ObjectId输入的 s(此处显示了它们对应的日期值)。

ObjectId(), Dec 10 2019
ObjectId(), Dec 10 2019
ObjectId("5c6b8f57f3558c2685b0d4e3"), Feb 19 2019
ObjectId("5c6b95a7f3558c2685b0d4e4"), Feb 19 2019
ObjectId("5c6b95a7f3558c2685b0d4e5"), Feb 19 2019
ObjectId("5dd525c60fd48753f98ea39b"), Nov 20 2019
ObjectId("5dd525c60fd48753f98ea39c"), Nov 20 2019
ObjectId("5dd525c60fd48753f98ea3a1"), Nov 20 2019
ObjectId("5dd60eaeae3321b020320583"), Nov 21 2019

并且,变量past_x_days = 30 * 86400000. 查询返回:

{ "count" : 2, "dateDMY" : "10-12-2019" }
{ "count" : 1, "dateDMY" : "21-11-2019" }
{ "count" : 3, "dateDMY" : "20-11-2019" }

推荐阅读