特殊的mongo统计,该怎么写?

mongo数据项形似如下:

{'key1':1,'key2':{'a':'1','b':2,'c':3,'d':''}}
{'key1':3,'key2':{'d':'','ty':2,'gh':3,'sd':''}}
{'key1':5,'key2':{'k':'1','b':2,'d':''}}
{'key1':2,'key2':{'q':1,'bf':2,'cw':3,'d':''}}
{'key1':1,'key2':{'su':'','b':2,'c':3,'d':''}}
{'key1':5,'key2':{'ba':1,'d':''}}
{'key1':1,'key2':{'er':'','b':2,'g':'','d':''}}

每条数据的key2中的key都各不相同,有多有少,value也有的为空。
我想统计 针对每一种key1,其key2的value完整度平均比例

很拗口是不是?我解释一下。

也就是首先按key1分组,我们看到key一共有 1,2,3,5 四种,所以分为四组。

其中1这一组,有3条,分别是:

{'key1':1,'key2':{'a':1,'b':2,'c':3,'d':''}}
{'key1':1,'key2':{'su':'','b':2,'c':3,'d':''}}
{'key1':1,'key2':{'er':'','b':2,'g':'','d':''}}

这三条中,第一条的key2,a,b,c都不是空字符串'',d是,那么第一条的完整度为 3/4 = 75%
以此计算,第二条与第三条的完整度分别是 50% 和 25%
最后计算 这三条的平均完整度是 (75%+50%+25%)/3 = 50%

对每一组都进行如上统计,最后得出这样的结果:

{'_id':1,'num':50%}
{'_id':2,'num':75%}
{'_id':3,'num':50%}
{'_id':5,'num':58%}

这样的统计在mongo里该怎么写呢?在pymongo里能写出对应的吗?

阅读 695
评论 更新于 2018-01-24
    2 个回答

    回来赴约了。这个查询可以这样写。大概就是用map/reduce的思路来处理。剩下的就是如何使用$map, $reduce, $let, $objectToArray这些东西的问题。先看看能不能理解一下,有不明白的地方再讨论。

    db.test.aggregate([{
        $project: {
            key1: 1,
            percentage: {
                $let: {
                    vars: {
                        key2: {
                            $reduce: {
                                input: {
                                    $map: {
                                        input: {
                                            $objectToArray: "$key2"
                                        },
                                        as: "keys",
                                        in: {
                                            $cond: [{
                                                $eq: ["$$keys.v", ""]
                                            }, 0, 1]
                                        }
                                    }
                                },
                                initialValue: {
                                    complete: 0,
                                    total: 0
                                },
                                in: {
                                    complete: {
                                        $add: ["$$value.complete", "$$this"]
                                    },
                                    total: {
                                        $add: ["$$value.total", 1]
                                    }
                                }
                            }
                        }
                    },
                    in: {
                        $divide: ["$$key2.complete", "$$key2.total"]
                    }
                }
            }
        }
    }, {
        $group: {
            _id: "$key1",
            percentage: {
                $avg: "$percentage"
            }
        }
    }])

    以你的数据跑出的结果是:

    { "_id" : 2, "percentage" : 0.75 }
    { "_id" : 5, "percentage" : 0.5833333333333333 }
    { "_id" : 3, "percentage" : 0.5 }
    { "_id" : 1, "percentage" : 0.5 }
    评论 赞赏 2018-01-26
      正在输入
      • 0
      • 新人请关照

      mongodb有一个操作符$group

      评论 赞赏 2018-01-24
        撰写回答

        登录后参与交流、获取后续更新提醒

        MongoDB 技术问答
        合作问答

        MongoDB 官方中文社区 和 SegmentFault 联合推出的 MongoDB 技术交流平台。 这是一个以社区力量为主,但...