鍍金池/ 問答/Python  數(shù)據(jù)庫  網(wǎng)絡(luò)安全/ 特殊的mongo統(tǒng)計,該怎么寫?

特殊的mongo統(tǒng)計,該怎么寫?

mongo數(shù)據(jù)項形似如下:

{'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':''}}

每條數(shù)據(jù)的key2中的key都各不相同,有多有少,value也有的為空。
我想統(tǒng)計 針對每一種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%

對每一組都進(jìn)行如上統(tǒng)計,最后得出這樣的結(jié)果:

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

這樣的統(tǒng)計在mongo里該怎么寫呢?在pymongo里能寫出對應(yīng)的嗎?

回答
編輯回答
悶騷型

mongodb有一個操作符$group

2017年6月8日 23:31
編輯回答
墨染殤

回來赴約了。這個查詢可以這樣寫。大概就是用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"
        }
    }
}])

以你的數(shù)據(jù)跑出的結(jié)果是:

{ "_id" : 2, "percentage" : 0.75 }
{ "_id" : 5, "percentage" : 0.5833333333333333 }
{ "_id" : 3, "percentage" : 0.5 }
{ "_id" : 1, "percentage" : 0.5 }
2018年3月17日 00:16