计算汇总选择中的结果

时间:2018-12-22 09:10:17

标签: mongodb

我的MongoDB数据库具有结构


    {
        "_id" : ObjectId("5c1ccc20fc0f60769227d455"),
        "type" : 0,
        "id" : "hwJyzAHyfjXUlrGhblT7txWd",
        "userowner" : 1.0,
        "campid" : "9548",
        "date" : 1545391136,
        "useragent" : "mozilla/5.0 (windows nt 10.0; win64; x64; rv:65.0) gecko/20100101 firefox/65.0",
        "domain" : "",
        "referer" : "",
        "country" : "en",
        "language" : "en-US",
        "languages" : [ 
            "en-US", 
            "en"
        ],
        "screenres" : [ 
            "1920*1080"
        ],
        "avscreenres" : [ 
            "1080*1858"
        ],
        "webgl" : "angle (nvidia geforce gtx 1060 6gb direct3d11 vs_5_0 ps_5_0)",
        "hash" : 123,
        "timezone" : -180,
        "result" : true,
        "resultreason" : "learning",
        "remoteip" : "0.0.0.0"
    }

每个文档的字段“结果”均为bool值。 我进行聚合选择:


    db.getCollection('clicks').aggregate([
        { $match: {userowner: 1, date:{$gte: 0, $lte: 9545392055}} },
        { $group : {_id : "$campid",
                number: {$sum: 1}}}
    ])

并获得结果:


    /* 1 */
    {
        "_id" : "4587",
        "number" : 2.0
    }

    /* 2 */
    {
        "_id" : "9548",
        "number" : 1346.0
    }

如何在字段“结果”中计算值“真”和“假”的数量并获得如下结果:


    /* 1 */
    {
        "_id" : "4587",
        "number" : 2.0,
        "passed":100,
        "blocked":120
    }

    /* 2 */
    {
        "_id" : "9548",
        "number" : 1346.0,
        "passed":100,
        "blocked":120
    }

2 个答案:

答案 0 :(得分:1)

我希望这可以按照您的要求进行。

def _violation(self, g, y, i):
    smallest = np.inf
    for k in range(g.shape[0]):
        if k == y[i] and self.dual_coef_[k, i] >= self.C:
            continue
        elif k != y[i] and self.dual_coef_[k, i] >= 0:
            continue

        smallest = min(smallest, g[k].all()) # and i added .all()
    return g.max() - smallest

输出:-

db.getCollection('clicks').aggregate(
[
    {
        $match: {
            userowner: 1, date: {
                $gte: 0, $lte: 9545392055
            }
        }
    },
    {
        $group: {
            _id: "$campid", passed: {
                $sum: {
                    $cond:
                        [
                            { $eq: ["$result", true] },
                            1, 0
                        ]
                }
            },
            blocked: {
                $sum: {
                    $cond:
                        [
                            {
                                $eq: ["$result", false]
                            }

                            , 1, 0]
                }
            },
            number: { $sum: 1 }
        }
    },
    {
        $project: {
            _id: 0,
            campid: "$_id",
            number: 1,
            passed: 1,
            blocked: 1
        }
    }

])

请参阅$ group$cond,$eq以获取更多信息。

答案 1 :(得分:0)

使用MongoDb 3.6及更高版本,您可以在 $arrayToObject 管道中利用 $replaceRoot 运算符来获得所需的结果。

您将需要按原始文件将其按Campid和结果字段分组,汇总总和并将结果传递到另一个分组管道阶段。这个小组阶段将以 $arrayToObject 运算符将使用$ push创建键值数组的方式为您提供所需对象的方式来准备文档。

然后将由此产生的结果馈送到 $replaceRoot 管道中,以将传递的字段和阻止的字段带到文档的根目录。

以下汇总管道描述了上述内容:

db.getCollection('clicks').aggregate([
    { "$match": { "userowner": 1, "date": { "$gte": 0, "$lte": 9545392055 } } },
    { "$group": {
        "_id": {  
            "campid": "$campid",  
            "result": { "$cond": [ "$result", "passed", "blocked" ] }
        },
        "count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.campid",
        "number": { "$sum": "$count" },
        "counts": {
            "$push": {
                "k": "$_id.result",
                "v": "$count"
            }
        }
    } },
    { "$replaceRoot": { 
        "newRoot": { 
            "$mergeObjects": [ 
                { "$arrayToObject": "$counts" }, 
                "$$ROOT" 
            ] 
        } 
    } },
    { "$project": { "counts": 0 } }
])