MongoDB聚合:如何根据条件获取列数

时间:2013-12-03 22:11:28

标签: mongodb

我有以下文件:

{ "col1": "camera", "fps": 1, "lat": 3 },
{ "col1": "camera", "fps": 3, "lat": 2 }
{ "col1": "camera", "foo": 9, "bar": 7 }
{ "col1": "camera", "bar": 8, "bar": 1 }
{ "col1": "camera", "check": 4, "lat": 3 }

我如何获得以下内容:

{ "fps": 2, "lat": 3, "bar": 3, "check": 1, "foo": 1 }

其中每个值都是每个键的出现次数(计数)(fps出现2,foo,出现一次等)

1 个答案:

答案 0 :(得分:0)

<强>汇总

这是一个解决方案(我命名为我的集合cameras),如果事先知道密钥:

 db.cameras.aggregate([
{
    $project: {
        _id: 1,
        fps: {
            $ifNull: [ "$fps", 0 ]
        },
        lat: {
            $ifNull: [ "$lat", 0 ]
        },
        bar: {
            $ifNull: [ "$bar", 0 ]
        },
        foo: {
            $ifNull: [ "$foo", 0 ]
        },
        check: {
            $ifNull: [ "$check", 0 ]
        }
    }
},
{
    $project: {
        _id: 1,
        fps: {
            $cond: [ { $eq: [ "$fps", 0 ] } , 0, 1 ]
        },
        lat: {
            $cond: [ { $eq: [ "$lat", 0 ] } , 0, 1 ]
        },
        bar: {
            $cond: [ { $eq: [ "$bar", 0 ] } , 0, 1 ]
        },
        foo: {
            $cond: [ { $eq: [ "$foo", 0 ] } , 0, 1 ]
        },
        check: {
            $cond: [ { $eq: [ "$check", 0 ] } , 0, 1 ]
        }
    }
},
{
    $group: {
        _id: null,
        fps: {
            $sum: "$fps"
        },
        lat: {
            $sum: "$lat"
        },
        bar: {
            $sum: "$bar"
        },
        foo: {
            $sum: "$foo"
        },
        check: {
            $sum: "$check"
        }
    }
}
])

结果:

{
    "result" : [
        {
            "_id" : null,
            "fps" : 2,
            "lat" : 3,
            "bar" : 2,
            "foo" : 1
        }
    ],
    "ok" : 1
}

<强>的MapReduce

如果键未知,则另一种解决方案是mapReduce:

db.cameras.mapReduce(
    function() {
        var keys = Object.keys(this);
        keys.forEach(function(key) {
            emit(key, 1);
        });
    },
    function(key, values) {
        return Array.sum(values);
    },
    {
        query: {},
        out: {
            inline: 1
        }
    }
)

结果:

{
    "results" : [
        {
            "_id" : "_id",
            "value" : 5
        },
        {
            "_id" : "bar",
            "value" : 2
        },
        {
            "_id" : "check",
            "value" : 1
        },
        {
            "_id" : "col1",
            "value" : 5
        },
        {
            "_id" : "foo",
            "value" : 1
        },
        {
            "_id" : "fps",
            "value" : 2
        },
        {
            "_id" : "lat",
            "value" : 3
        }
    ],
    "timeMillis" : 1,
    "counts" : {
        "input" : 5,
        "emit" : 19,
        "reduce" : 5,
        "output" : 7
    },
    "ok" : 1,
}

但结果并不完全相同。