首页 > 解决方案 > 查询没有数组的嵌套字段

问题描述

对于以下文档“27”,“28”是当月的天数,而“27”下的“6”到“11”代表小时,我希望能够仅检索每个小时的用户数组使用 python 进行一些处理,或者理想情况下捕获一整天的用户数组,但如果我可以每小时访问用户,我可以使用 python 做到这一点没问题。

{
        "values" : {
                "27" : {
                        "6" : {
                                "users" : [
                                        "5b5abc5ddd601f0b6681358a"
                                ],
                                "values" : {
                                        "5b5abc5ddd601f0b6681358a" : 2
                                }
                        },
                        "7" : {
                                "users" : [
                                        "5b5ac75cdd601f0b668157ff",
                                        "5b5acd0ddd601f0b66816803"
                                ],
                                "values" : {
                                        "5b5ac75cdd601f0b668157ff" : 1,
                                        "5b5acd0ddd601f0b66816803" : 4
                                }
                        },
                        "8" : {
                                "users" : [
                                        "5b5acd0ddd601f0b66816803"
                                ],
                                "values" : {
                                        "5b5acd0ddd601f0b66816803" : 2
                                }
                        },
                        "9" : {
                                "users" : [
                                        "5b5acd0ddd601f0b66816803",
                                        "5b5ae89b781e011702f00812"
                                ],
                                "values" : {
                                        "5b5acd0ddd601f0b66816803" : 2,
                                        "5b5ae89b781e011702f00812" : 3
                                }
                        },
                        "10" : {
                                "users" : [
                                        "5b5ae89b781e011702f00812"
                                ],
                                "values" : {
                                        "5b5ae89b781e011702f00812" : 1
                                }
                        }
                },
                "28" : {
                        "11" : {
                                "users" : [
                                        "5b5abacadd601f0b6681312e"
                                ],
                                "values" : {
                                        "5b5abacadd601f0b6681312e" : 1
                                }
                        }
                }
        }
}

问题是因为这里没有数组,所以展开不起作用,还有几天和几个小时没有活动,所以没有可用的数据。

标签: mongodbnosqlmongodb-queryaggregation-frameworkpymongo

解决方案


您需要$objectToArray才能使用动态键名。然后,您可以应用$map结合$reduce来展平您的数据模型和$arrayToObject以获得以天为键的结果:

db.col.aggregate([
    {
        $project: {
            days: {
                $map: {
                    input: { $objectToArray: "$values" },
                    as: "day",
                    in: {
                        k: "$$day.k",
                        v: {
                            $map: { 
                                input: { $objectToArray: "$$day.v" },
                                as: "h",
                                in: {
                                    $map: {
                                        input: { $objectToArray: "$$h.v.values" },
                                        as: "pair",
                                        in: "$$pair.k"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $project: {
            days: {
                $arrayToObject: {
                    $map: {
                        input: "$days",
                        as: "day",
                        in: {
                            k: "$$day.k",
                            v: {
                                $reduce: {
                                    input: "$$day.v",
                                    initialValue: [],
                                    in: { $concatArrays: [ "$$this", "$$value" ] }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
])

印刷:

{
    "days" : {
            "27" : [
                    "5b5ae89b781e011702f00812",
                    "5b5acd0ddd601f0b66816803",
                    "5b5ae89b781e011702f00812",
                    "5b5acd0ddd601f0b66816803",
                    "5b5ac75cdd601f0b668157ff",
                    "5b5acd0ddd601f0b66816803",
                    "5b5abc5ddd601f0b6681358a"
            ],
            "28" : [
                    "5b5abacadd601f0b6681312e"
            ]
    }
}

推荐阅读