MongoDB聚合组数组到键:求和值 [英] MongoDB aggregate group array to key : sum value

查看:153
本文介绍了MongoDB聚合组数组到键:求和值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我是mongodb的新手,正在尝试将具有不同类型(int)的对象转换为键值对.

Hello I am new to mongodb and trying to convert objects with different types (int) into key value pairs.

我有这样的收藏夹:

{
    "_id" : ObjectId("5372a9fc0079285635db14d8"),
    "type" : 1,
    "stat" : "foobar"
},
{
    "_id" : ObjectId("5372aa000079285635db14d9"),
    "type" : 1,
    "stat" : "foobar"
},
{
    "_id" : ObjectId("5372aa010079285635db14da"),
    "type" : 2,
    "stat" : "foobar"
},{
    "_id" : ObjectId("5372aa030079285635db14db"),
    "type" : 3,
    "stat" : "foobar"
}

我想要这样的结果:

{
    "type1" : 2, "type2" : 1, "type3" : 1,
    "stat" : "foobar"
}

当前正在尝试聚合组,然后将类型值推入数组

Currently trying aggregation group and then push type values to array

db.types.aggregate(
    {$group : {
        _id : "$stat",
        types : {$push : "$type"}
    }}
)

但是不知道如何求和不同类型并将其转换为键值

But don't know how to sum different types and to convert it into key values

/* 0 */
{
    "result" : [ 
        {
            "_id" : "foobar",
            "types" : [ 
                1, 
                2, 
                2, 
                3
            ]
        }
    ],
    "ok" : 1
}

推荐答案

对于您的实际表单,因此假设您实际上知道类型"的可能值,则可以使用两个

For your actual form, and therefore presuming that you actually know the possible values for "type" then you can do this with two $group stages and some use of the $cond operator:

db.types.aggregate([
    { "$group": {
         "_id": {
             "stat": "$stat",
             "type": "$type"
         },
         "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": "$_id.stat",
        "type1": { "$sum": { "$cond": [
            { "$eq": [ "$_id.type", 1 ] },
            "$count",
            0
        ]}},
        "type2": { "$sum": { "$cond": [
            { "$eq": [ "$_id.type", 2 ] },
            "$count",
            0
        ]}},
        "type3": { "$sum": { "$cond": [
            { "$eq": [ "$_id.type", 3 ] },
            "$count",
            0
        ]}}
    }}
])

确切给出了以下内容:

{ "_id" : "foobar", "type1" : 2, "type2" : 1, "type3" : 1 }

我实际上更喜欢使用两个 $group 阶段:

I actually prefer the more dynamic form with two $group stages though:

db.types.aggregate([
    { "$group": {
         "_id": {
             "stat": "$stat",
             "type": "$type"
         },
         "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": "$_id.stat",
        "types": { "$push": {
            "type": "$_id.type",
            "count": "$count"
        }}
    }}
])

输出不相同,但功能和值灵活:

Not the same output but functional and flexible to the values:

{
    "_id" : "foobar",
    "types" : [
            {
                    "type" : 3,
                    "count" : 1
            },
            {
                    "type" : 2,
                    "count" : 1
            },
            {
                    "type" : 1,
                    "count" : 2
            }
    ]
}

否则,如果您需要相同的输出格式,但需要灵活的字段,则可以始终使用mapReduce,但输出并不完全相同.

Otherwise if you need the same output format but need the flexible fields then you can always use mapReduce, but it's not exactly the same output.

db.types.mapReduce(
    function () {

        var obj = { };

        var key = "type" + this.type;
        obj[key] = 1;

        emit( this.stat, obj );

    },
    function (key,values) {

        var obj = {};

        values.forEach(function(value) {
            for ( var k in value ) {
                if ( !obj.hasOwnProperty(k) )
                    obj[k] = 0;
                obj[k]++;
            }
        });

        return obj;

    },
    { "out": { "inline": 1 } }
)

并采用典型的mapReduce样式:

And in typical mapReduce style:

   "results" : [
            {
                    "_id" : "foobar",
                    "value" : {
                            "type1" : 2,
                            "type2" : 1,
                            "type3" : 1
                    }
            }
    ],

但这是您的选择

这篇关于MongoDB聚合组数组到键:求和值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆