MongoDB聚合组数组到键:求和值 [英] MongoDB aggregate group array to key : sum value
问题描述
您好,我是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
}
推荐答案
对于您的实际表单,因此假设您实际上知道类型"的可能值,则可以使用两个 $cond
运算符:
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屋!