当您将 unix 时间存储为时间戳时,如何对过去 12 个月的文档进行分组?
How to group documents for the last 12 months, month wise when you have unix time stored as timeStamp?
我有一个集合,其中数据每天根据 unix 纪元时间更新。例如:
{
"uID" : "12345678",
"midNightTimeStamp" : NumberInt(1645381800), // 21st Feb 2022 midnight IST
"energyConsumed" : NumberInt(53)
},
{
"uID" : "12345678",
"midNightTimeStamp" : NumberInt(1645641000), // 24th Feb 2022 midnight IST
"energyConsumed" : NumberInt(30)
}
现在如果您想按月查询最近 12 个月的数据,您会采用什么方法来解决这个问题?我所知道的是,我可以像这样在聚合查询中对数据进行分组:
$project: {
energyConsumed: 1.0,
year: {
$year: // How would you convert this from epoch
},
month: {
$month: // How would you convert this from epoch
}
},
现在,如果我想将过去 12 个月的数据分组为这样的东西
$group: {
_id: '$month',
energyConsumed: {
$sum: '$energyConsumed'
}
}
我想要的输出是:
{
id: 04 // (something like 04 or just April but data should be sorted month and year wise April 2021),
energyConsumed: 4179772
},
{
id: 05 // (something like 05 or just May but data should be sorted month and year wise),
energyConsumed: 6179772
},
...
...
{
id: 03 // (something like 03 or just March (March 2022),
energyConsumed: 5643772
}
也许是这样:
db.collection.aggregate([
{
$group: {
_id: {
$dateToString: {
format: "%Y-%m",
date: {
$toDate: {
"$multiply": [
"$midNightTimeStamp",
1000
]
}
}
}
},
monthlyConsumption: {
$sum: "$energyConsumed"
}
}
}
])
解释:
$group 基于Year-Month ("YYYY-mm" ) 提取的midNightTimeStamp 字段和$sum 每月消费
要赶上从现在开始的最后 12 个月,请将其放在上面 $group
阶段的前面:
// Back up one year from right now:
var sdate = new ISODate();
sdate.setYear((sdate.getYear()-1) + 1900);
db.foo.aggregate([
{$match: {$expr: {$gt:[{$toDate: {$multiply:['$midNightTimeStamp',1000]}},sdate]} } },
{$group: { ... // as above
如果您 运行 已经 MongoDB 版本 5.0 那么您可以使用 $dateTrunc:
db.collection.aggregate([
{
$group: {
_id: {
$dateTrunc: {
date: { $toDate: { $toLong: { $multiply: ["$midNightTimeStamp", 1000] } } },
unit: "month",
timezone: "Europe/Zurich"
}
},
energyConsumed: { $sum: "$energyConsumed" }
}
}
])
由于 timezone
选项,它可能比 $dateToString: { format: "%Y-%m" ...
更精确。
我有一个集合,其中数据每天根据 unix 纪元时间更新。例如:
{
"uID" : "12345678",
"midNightTimeStamp" : NumberInt(1645381800), // 21st Feb 2022 midnight IST
"energyConsumed" : NumberInt(53)
},
{
"uID" : "12345678",
"midNightTimeStamp" : NumberInt(1645641000), // 24th Feb 2022 midnight IST
"energyConsumed" : NumberInt(30)
}
现在如果您想按月查询最近 12 个月的数据,您会采用什么方法来解决这个问题?我所知道的是,我可以像这样在聚合查询中对数据进行分组:
$project: {
energyConsumed: 1.0,
year: {
$year: // How would you convert this from epoch
},
month: {
$month: // How would you convert this from epoch
}
},
现在,如果我想将过去 12 个月的数据分组为这样的东西
$group: {
_id: '$month',
energyConsumed: {
$sum: '$energyConsumed'
}
}
我想要的输出是:
{
id: 04 // (something like 04 or just April but data should be sorted month and year wise April 2021),
energyConsumed: 4179772
},
{
id: 05 // (something like 05 or just May but data should be sorted month and year wise),
energyConsumed: 6179772
},
...
...
{
id: 03 // (something like 03 or just March (March 2022),
energyConsumed: 5643772
}
也许是这样:
db.collection.aggregate([
{
$group: {
_id: {
$dateToString: {
format: "%Y-%m",
date: {
$toDate: {
"$multiply": [
"$midNightTimeStamp",
1000
]
}
}
}
},
monthlyConsumption: {
$sum: "$energyConsumed"
}
}
}
])
解释:
$group 基于Year-Month ("YYYY-mm" ) 提取的midNightTimeStamp 字段和$sum 每月消费
要赶上从现在开始的最后 12 个月,请将其放在上面 $group
阶段的前面:
// Back up one year from right now:
var sdate = new ISODate();
sdate.setYear((sdate.getYear()-1) + 1900);
db.foo.aggregate([
{$match: {$expr: {$gt:[{$toDate: {$multiply:['$midNightTimeStamp',1000]}},sdate]} } },
{$group: { ... // as above
如果您 运行 已经 MongoDB 版本 5.0 那么您可以使用 $dateTrunc:
db.collection.aggregate([
{
$group: {
_id: {
$dateTrunc: {
date: { $toDate: { $toLong: { $multiply: ["$midNightTimeStamp", 1000] } } },
unit: "month",
timezone: "Europe/Zurich"
}
},
energyConsumed: { $sum: "$energyConsumed" }
}
}
])
由于 timezone
选项,它可能比 $dateToString: { format: "%Y-%m" ...
更精确。