mongodb - 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
解决方案
假设该_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" }
推荐阅读
- angularjs - 如何在 ES6 中导入名称中带有连字符的 angularjs 模块
- bitbucket - 尝试签出项目时,BitBucket 无法打开 SourceTree 弹出屏幕
- ssl - 是否可以在 Tomcat 上安装没有私钥的通配符证书?
- node.js - 节点缓冲区别名 - 二进制是 latin1?
- android - 如何使图像上传不只是从相机?
- redirect - 使用 .htacces 重定向图像 - 保留 url
- python - 如何在不更改参数名称的情况下装饰 Python 函数?
- android - 如何让 SQLite 与我的复选框一起使用
- android - 构建签名 APK 时出现“程序类型已存在”错误
- python - 如果之前有换行符,则截断树