MongoDB:使用_id统计过去X天中每天创建的文档数
我希望在我的网站上收集用户的注册统计数据——通过mongo shell按日期统计过去X天的注册数量。结果可能类似于:MongoDB:使用_id统计过去X天中每天创建的文档数,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我希望在我的网站上收集用户的注册统计数据——通过mongo shell按日期统计过去X天的注册数量。结果可能类似于: Dec 7, 2019: 100 Dec 6, 2019: 150 Dec 5, 2019: 150 ... 文档没有在属性处创建任何,但是有一个\u id属性,我相信可以用来实现这个目标 如果这有助于更清楚地理解,MySQL中的等效项将类似于SELECT count(id)FROM Users WHERE created_at>timestamp_X_days_ago GRO
Dec 7, 2019: 100
Dec 6, 2019: 150
Dec 5, 2019: 150
...
文档没有在属性处创建任何,但是有一个\u 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({“\u-id”:{$lt:new-Date(),$gte:new-Date(new-Date().setDate().getDate()-1))}).count()
,只要\u-id
我知道如何在\u-id
上强制转换日期
Mongo 3.6假设\u id
字段为类型,下面的查询按天按降序打印计数
初始匹配阶段将按“最后X天”筛选文档。例如,要仅处理从今天开始的过去10天的文档,请以毫秒为单位获取过去10天的,并在查询中使用它:
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(此处显示了相应的日期值)
并且,变量过去的天数=30*86400000
。查询返回:
{ "count" : 2, "dateDMY" : "10-12-2019" }
{ "count" : 1, "dateDMY" : "21-11-2019" }
{ "count" : 3, "dateDMY" : "20-11-2019" }
您可以在MongoShell中使用下面的聚合查询来实现高效搜索。首先执行匹配,然后执行到日期的转换以进行分组
var lastWeek = new Date();
lastWeek.setDate(lastWeek.getDate() -7);
var lastWeekObjectId = ObjectId.fromDate(lastWeek);
db.Users.aggregate(
{$match:{_id:{$gt:lastWeekObjectId}}},
{$addFields:{_id:0,roundDate:{$dateFromParts:{
year:{$year:"$_id"},
month:{$month:"$_id"},
day:{$dayOfMonth:"$_id"}
}}}},
{$sortByCount:{$dateToString:{date:"$roundDate",format:"%m-%d-%Y"}}}
)
由于mongo ObjectId中有一个时间戳,因此可以使用此方法创建新的ObjectId,并将时间戳作为边界(下限和上限)进行比较:
db.Users.aggregate(
[
{
$match:{
_身份证:{
$gt:ObjectId(数学楼层((新日期('2019-08-28T22:55:00Z'))/1000)。toString(16)+“0000000000000000”),
$lt:ObjectId(数学楼层((新日期('2019-11-28T22:56:00Z'))/1000)。toString(16)+“0000000000000000”)
}
}
},
{
$项目:{
日期:{$dateToString:{格式:'%Y-%m-%d',日期:'$\U id'}
},
},
{
$group:{
_id:“$date”,
计数:{$sum:1}
}
},
{
$sort:{
_身份证号码:1
}
}
]
)
只需将日期更改为您想要查询的日期即可
因此,匹配查询根据对象的_id按日期过滤,然后当我们将得到的objectid转换为string、group by the day string、count和sort:)看到了吗。。没有帮助,除了\u id
中提供的日期字段之外,我没有任何其他日期字段\u id
的值是多少?@krishnaPrasad这是一个ObjectID
这个问题以前问过。谢谢。我们正在使用Mongo3,因此,$toDate
不起作用。现在正在检查Mongo 3中的替代方案。它是3.0、3.2、3.4还是3.6?它是MongoDB 3.6,就像$sortByCount
阶段,从未注意到它的存在。。。
var lastWeek = new Date();
lastWeek.setDate(lastWeek.getDate() -7);
var lastWeekObjectId = ObjectId.fromDate(lastWeek);
db.Users.aggregate(
{$match:{_id:{$gt:lastWeekObjectId}}},
{$addFields:{_id:0,roundDate:{$dateFromParts:{
year:{$year:"$_id"},
month:{$month:"$_id"},
day:{$dayOfMonth:"$_id"}
}}}},
{$sortByCount:{$dateToString:{date:"$roundDate",format:"%m-%d-%Y"}}}
)