【问题标题】:MongoDB: Aggregate with nested $groupMongoDB:使用嵌套的 $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,但在所有尝试中它都会出错。

这可能吗?如果可以,怎么做?

【问题讨论】:

    标签: node.js mongodb mongoose mongodb-query aggregation-framework


    【解决方案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 元素进行排序。无论如何,这个实现就足够了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2017-07-26
    • 2017-07-16
    • 2019-07-20
    • 1970-01-01
    • 2020-03-08
    • 2021-12-17
    相关资源
    最近更新 更多