MongoDB:使用嵌套的 $group 聚合
Posted
技术标签:
【中文标题】MongoDB:使用嵌套的 $group 聚合【英文标题】:MongoDB: Aggregate with nested $group 【发布时间】:2019-01-31 22:56:03 【问题描述】:我有以下疑问:
db.test.aggregate([
$match:
'type': 'energy'
,
$limit: 10000
,
$addFields:
day:
$dateToString:
date: "$when.date",
format: "%d/%m/%Y"
,
sensor: "$id"
,
,
$project:
_id: 1,
sensor: 1,
when: 1,
value: 1,
day: 1
,
$group:
_id: "$day",
data:
$push: "$$ROOT"
,
,
$sort:
'data': 1
])
返回此数据格式:
"_id" : "05/04/2018", “数据” : [ "_id" : ObjectId("5ac66be9b02d5c18fd4106c7"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-05T13:53:22.703-03:00”), “Unix”:1522947202, “毫”:1522947202703 , “天”:“2018 年 5 月 4 日”, “传感器”:“sen3” , "_id" : ObjectId("5ac66be9b02d5c18fd4106c8"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-05T13:53:22.705-03:00”), “Unix”:1522947202, “毫”:1522947202705 , “天”:“2018 年 5 月 4 日”, “传感器”:“sen4” ] , "_id" : "06/04/2018", “数据” : [ "_id" : ObjectId("5ac7e5d2efe88a4e76c008d2"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-06T18:25:38.885-03:00”), “Unix”:1523049938, “毫”:1523049938885 , “天”:“2018 年 6 月 4 日”, “传感器”:“sen3” , “_id”:ObjectId(“5ac7e5e4efe88a4e76c008d5”), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-06T18:25:56.105-03:00”), “Unix”:1523049956, “毫”:1523049956105 , “天”:“2018 年 6 月 4 日”, “传感器”:“sen3” ] ,...
请注意,我们在每个“数据”文档中都有不同类型的传感器(sen3、sen4、...、senN)。
我正在尝试再次聚合此结果,按传感器对数据进行分组,以获得如下输出:
"_id" : "05/04/2018", “森3”:[ "_id" : ObjectId("5ac66be9b02d5c18fd4106c7"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-05T13:53:22.703-03:00”), “Unix”:1522947202, “毫”:1522947202703 , “天”:“2018 年 5 月 4 日”, “传感器”:“sen3” , "_id" : ObjectId("5ac66be9b02d5c18fd4106c7"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-05T13:53:22.703-03:00”), “Unix”:1522947202, “毫”:1522947202703 , “天”:“2018 年 5 月 4 日”, “传感器”:“sen3” ], “sen4”:[ "_id" : ObjectId("5ac66be9b02d5c18fd4106c8"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-05T13:53:22.705-03:00”), “Unix”:1522947202, “毫”:1522947202705 , “天”:“2018 年 5 月 4 日”, “传感器”:“sen4” , "_id" : ObjectId("5ac66be9b02d5c18fd4106c8"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-05T13:53:22.705-03:00”), “Unix”:1522947202, “毫”:1522947202705 , “天”:“2018 年 5 月 4 日”, “传感器”:“sen4” ] , "_id" : "06/04/2018", “森3”:[ "_id" : ObjectId("5ac7e5d2efe88a4e76c008d2"), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-06T18:25:38.885-03:00”), “Unix”:1523049938, “毫”:1523049938885 , “天”:“2018 年 6 月 4 日”, “传感器”:“sen3” , “_id”:ObjectId(“5ac7e5e4efe88a4e76c008d5”), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-06T18:25:56.105-03:00”), “Unix”:1523049956, “毫”:1523049956105 , “天”:“2018 年 6 月 4 日”, “传感器”:“sen3” ], “sen4”:[ “_id”:ObjectId(“5ac7e7a7efe88a4e76c008de”), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-06T18:33:27.365-03:00”), “Unix”:1523050407, “毫”:1523050407365 , “天”:“2018 年 6 月 4 日”, “传感器”:“sen4” , “_id”:ObjectId(“5ac7e7a7efe88a4e76c008de”), “价值”:0, “什么时候” : “日期”:ISODate(“2018-04-06T18:33:27.365-03:00”), “Unix”:1523050407, “毫”:1523050407365 , “天”:“2018 年 6 月 4 日”, “传感器”:“sen4” ]简而言之:我想在天、传感器和每个传感器内对数据进行分组属于那天和传感器。
我正在尝试创建一个嵌套的$group
,但在所有尝试中它都会出错。
这可能吗?如果可以,怎么做?
【问题讨论】:
【参考方案1】:您可以在 mongodb 3.6 及更高版本中尝试以下聚合
db.collection.aggregate([
"$match": "type": "energy" ,
"$limit": 10000 ,
"$addFields":
"day": "$dateToString": "date": "$when.date", "format": "%d/%m/%Y" ,
"sensor": "$id"
,
"$project": "_id": 1, "sensor": 1, "when": 1, "value": 1, "day": 1 ,
"$group":
"_id": "day": "$day", "sensor": "$sensor" ,
"data": "$push": "$$ROOT"
,
"$group":
"_id": "day": "$_id.day" ,
"data": "$push": "k": "$_id.sensor", "v": "$data"
,
"$addFields": "data": "$arrayToObject": "$data" ,
"$replaceRoot": "newRoot": "$mergeObjects": [ "$_id", "$data" ]
])
【讨论】:
它很好地解决了这个问题。但是输出没有给我按日期(天)或传感器排序。当我在末尾添加一个 $sort: 'day': 1 时,它按字符串 day 的第一个元素排序,而不是按日期排序。有没有办法让它正确?谢谢你! 你想在哪一天$sort
?在sen
数组内?
我只想按 sen 数组外的 day 元素进行排序。无论如何,这个实现就足够了。谢谢!以上是关于MongoDB:使用嵌套的 $group 聚合的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB 聚合比较:group()、$group 和 MapReduce
MongoDb 聚合在 $group 中使用 $sortByCount