查询没有数组的嵌套字段

时间:2018-07-29 12:58:56

标签: mongodb nosql mongodb-query aggregation-framework pymongo

对于以下文档“ 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
                                }
                        }
                }
        }
}

问题是因为这里没有数组,所以展开无法正常工作,而且在几天和几小时内没有活动,因此没有可用的数据。

1 个答案:

答案 0 :(得分:1)

您需要$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"
            ]
    }
}