在MongoDBShell中,如何查询某个时间段(比如一个月)的每日数据
In MongoDB Shell, How to query for day-by-day data for a time period (such as a month)
我想获取按 class(我的集合中的字段)分组的一天数据,持续一个月。
这是我试图查询的内容,但没有给出预期的输出。
查询:
db.collection.aggregate([
// Get only records created in the last 30 days
{$match:{
"created_at":{$gt: new Date(ISODate().getTime() - 1000*60*60*24*30)},
}},
// Get the year, month and day from the created_at TimeStamp
{$project:{
"year":{$year:"$created_at"},
"month":{$month:"$created_at"},
"day": {$dayOfMonth:"$created_at"}
}},
// Group by year, month and day and get the count
{$group:{
_id:{year:"$year", month:"$month", day:"$day"},
"count":{$sum:1}
}},
// Group by class field
{ $group: {
_id: "$meta.class",
total: {$sum: 1}
}}
])
预期输出:
{ "_id" : { "year" : 2021, "month" : 10, "day" : 01 }, "count" : {{ "_id" : "class1", "total" : 15 }, { "_id" : "class2", "total" : 25 }} }
{ "_id" : { "year" : 2021, "month" : 10, "day" : 02 }, "count" : {{ "_id" : "class2", "total" : 25 }, { "_id" : "class3", "total" : 10 }} }
...
{ "_id" : { "year" : 2021, "month" : 10, "day" : 30 }, "count" : {{ "_id" : "class3", "total" : 50 }} }
所以,有人可以告诉我如何达到预期的结果或者我做错了什么吗?
谢谢。
---编辑---
示例数据:
mongoplayground link : here
[
{
"key": 1,
"_id": ObjectId("615602280000000000000000"),
"created_at": ISODate("2021-09-30T18:30:00.000Z"),
"meta": {
"class": "class1",
}
},
{
"key": 2,
"_id": ObjectId("615753a80000000000000000"),
"created_at": ISODate("2021-10-01T18:30:00.000Z"),
"meta": {
"class": "class1",
}
},
{
"key": 3,
"_id": ObjectId("615764100000000000000000"),
"created_at": ISODate("2021-10-01T19:40:00.000Z"),
"meta": {
"class": "class1",
}
},
{
"key": 4,
"_id": ObjectId("615776d00000000000000000"),
"created_at": ISODate("2021-10-01T21:00:00.000Z"),
"meta": {
"class": "class2",
}
}
]
样本o/p:
[
{
"_id":{
"year":2021,
"month":10,
"day":1
},
"count":[
{
"_id":"class1",
"total":1
}
]
},
{
"_id":{
"year":2021,
"month":10,
"day":2
},
"count":[
{
"_id":"class1",
"total":2
},
{
"_id":"class2",
"total":1
}
]
}
]
试试这个:
db.collection.aggregate([
{ $match: { created_at: { $gt: moment().startOf('day').subtract(30, 'day').toDate() } } },
{
$group: {
_id: {
day: { $dateTrunc: { date: "$created_at", unit: "day" } },
class: "$meta.class"
},
total: { $count: {} }
}
},
{
$group: {
_id: "$_id.day",
count: { $push: { total: "$total", class: "$_id.class" } }
}
}
])
每当我必须使用 date/time 值时,我建议使用 moment.js 库。
$dateTrunc()
需要 MongoDB 5.0 版。如果您喜欢或需要 year/month/day 部分,那么修改聚合管道的方法应该很明显。
我想获取按 class(我的集合中的字段)分组的一天数据,持续一个月。
这是我试图查询的内容,但没有给出预期的输出。
查询:
db.collection.aggregate([
// Get only records created in the last 30 days
{$match:{
"created_at":{$gt: new Date(ISODate().getTime() - 1000*60*60*24*30)},
}},
// Get the year, month and day from the created_at TimeStamp
{$project:{
"year":{$year:"$created_at"},
"month":{$month:"$created_at"},
"day": {$dayOfMonth:"$created_at"}
}},
// Group by year, month and day and get the count
{$group:{
_id:{year:"$year", month:"$month", day:"$day"},
"count":{$sum:1}
}},
// Group by class field
{ $group: {
_id: "$meta.class",
total: {$sum: 1}
}}
])
预期输出:
{ "_id" : { "year" : 2021, "month" : 10, "day" : 01 }, "count" : {{ "_id" : "class1", "total" : 15 }, { "_id" : "class2", "total" : 25 }} }
{ "_id" : { "year" : 2021, "month" : 10, "day" : 02 }, "count" : {{ "_id" : "class2", "total" : 25 }, { "_id" : "class3", "total" : 10 }} }
...
{ "_id" : { "year" : 2021, "month" : 10, "day" : 30 }, "count" : {{ "_id" : "class3", "total" : 50 }} }
所以,有人可以告诉我如何达到预期的结果或者我做错了什么吗? 谢谢。
---编辑---
示例数据:
mongoplayground link : here
[
{
"key": 1,
"_id": ObjectId("615602280000000000000000"),
"created_at": ISODate("2021-09-30T18:30:00.000Z"),
"meta": {
"class": "class1",
}
},
{
"key": 2,
"_id": ObjectId("615753a80000000000000000"),
"created_at": ISODate("2021-10-01T18:30:00.000Z"),
"meta": {
"class": "class1",
}
},
{
"key": 3,
"_id": ObjectId("615764100000000000000000"),
"created_at": ISODate("2021-10-01T19:40:00.000Z"),
"meta": {
"class": "class1",
}
},
{
"key": 4,
"_id": ObjectId("615776d00000000000000000"),
"created_at": ISODate("2021-10-01T21:00:00.000Z"),
"meta": {
"class": "class2",
}
}
]
样本o/p:
[
{
"_id":{
"year":2021,
"month":10,
"day":1
},
"count":[
{
"_id":"class1",
"total":1
}
]
},
{
"_id":{
"year":2021,
"month":10,
"day":2
},
"count":[
{
"_id":"class1",
"total":2
},
{
"_id":"class2",
"total":1
}
]
}
]
试试这个:
db.collection.aggregate([
{ $match: { created_at: { $gt: moment().startOf('day').subtract(30, 'day').toDate() } } },
{
$group: {
_id: {
day: { $dateTrunc: { date: "$created_at", unit: "day" } },
class: "$meta.class"
},
total: { $count: {} }
}
},
{
$group: {
_id: "$_id.day",
count: { $push: { total: "$total", class: "$_id.class" } }
}
}
])
每当我必须使用 date/time 值时,我建议使用 moment.js 库。
$dateTrunc()
需要 MongoDB 5.0 版。如果您喜欢或需要 year/month/day 部分,那么修改聚合管道的方法应该很明显。