【问题标题】:MongoDB - aggregating with nested objects, and changeable keysMongoDB - 具有嵌套对象和可变键的聚合
【发布时间】:2019-03-03 14:41:37
【问题描述】:

我有一份文档,其中描述了相机在 15 分钟内观察到的不同事物的计数。它看起来像这样:

{
    "_id" : ObjectId("5b1a709a83552d002516ac19"),
    "start" : ISODate("2018-06-08T11:45:00.000Z"),
    "end" : ISODate("2018-06-08T12:00:00.000Z"),
    "recording" : ObjectId("5b1a654683552d002516ac16"),
    "data" : {
        "counts" : {
            "5b434d05da1f0e00252566be" : 12,
            "5b434d05da1f0e00252566cc" : 4,
            "5b434d05da1f0e00252566ca" : 1
        }
    }
}

data.counts 对象中的键随每个文档更改,并引用稍后获取的其他数据。 data.counts 中有无限数量的键(但通常约为 20)

我正在尝试将所有这些 15 分钟的文档汇总为每日汇总文档。

我现在有这个查询:

db.getCollection("segments").aggregate([
    {$match:{
       "recording": ObjectId("5bf7f68ad8293a00261dd83f")
    }}, 
    {$project:{
        "start": 1,
        "recording": 1,
        "data": 1
    }},
    {$group:{
        _id: { $dateToString: { format: "%Y-%m-%d", date: "$start" } },
        "segments": { $push: "$$ROOT" }
    }},
    {$sort: {_id: -1}},
]);

这会进行分组并返回数组中的所有segments

我还想汇总data.counts 中的信息,以便获得每日组中所有相同键的值的总和。

这将使我免于在每 15 分钟的分段中使用相同的键对值进行另一个服务循环。例如。查询将返回如下内容:

{
    "_id" : "2019-02-27",
    "counts" : {
        "5b434d05da1f0e00252566be" : 351,
        "5b434d05da1f0e00252566cc" : 194,
        "5b434d05da1f0e00252566ca" : 111
        ... any other keys that were found within a day
    }
}

如何修改已有的查询,或使用不同的查询?

谢谢!

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    您可以使用$facet 管道阶段创建两个子管道;一个用于segments,另一个用于counts。这些子管道可以通过使用$zip 将它们拼接在一起并使用$map 来合并从 zip 生成的每个 2 元素数组。请注意,这只有在子管道输出相同大小的排序数组时才能正常工作,这就是我们在每个子管道中按start_date 分组和排序的原因。

    这是查询:

    db.getCollection("segments").aggregate([{
        $match: {
            recording: ObjectId("5b1a654683552d002516ac16")
        }
    }, {
        $project: {
            start: 1,
            recording: 1,
            data: 1,
            start_date: { $dateToString: { format: "%Y-%m-%d", date: "$start" }}
        }
    }, {
        $facet: {
            segments_pipeline: [{
                $group: {
                    _id: "$start_date",
                    segments: {
                        $push: {
                            start: "$start",
                            recording: "$recording",
                            data: "$data"
                        }
                    }
                }
            }, {
                $sort: {
                    _id: -1
                }
            }],
            counts_pipeline: [{
                $project: {
                    start_date: "$start_date",
                    count: { $objectToArray: "$data.counts" }
                }
            }, {
                $unwind: "$count"
            }, {
                $group: {
                    _id: {
                        start_date: "$start_date",
                        count_id: "$count.k"
                    },
                    count_sum: { $sum: "$count.v" }
                }
            }, {
                $group: {
                    _id: "$_id.start_date",
                    counts: {
                        $push: {
                            $arrayToObject: [[{
                                k: "$_id.count_id",
                                v: "$count_sum"
                            }]]
                        }
                    }
                }
            }, {
                $project: {
                    counts: { $mergeObjects: "$counts" }
                }
            }, {
                $sort: {
                    _id: -1
                }
            }]
        }
    }, {
        $project: {
            result: {
                $map: {
                    input: { $zip: { inputs: ["$segments_pipeline", "$counts_pipeline"] }},
                    in: { $mergeObjects: "$$this" }
                }
            }
        }
    }, {
        $unwind: "$result"
    }, {
        $replaceRoot: {
            newRoot: "$result"
        }
    }])
    

    在这里试用:Mongoplayground

    【讨论】:

      猜你喜欢
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 2015-03-10
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      相关资源
      最近更新 更多