[英]MongoDB aggregate group array to key : sum value
您好,我是mongodb的新手,正在嘗試將具有不同類型(int)的對象轉換為鍵值對。
我有這樣的收藏:
{
"_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"
}
當前正在嘗試聚合組,然后將類型值推入數組
db.types.aggregate(
{$group : {
_id : "$stat",
types : {$push : "$type"}
}}
)
但是不知道如何求和不同類型並將其轉換為鍵值
/* 0 */
{
"result" : [
{
"_id" : "foobar",
"types" : [
1,
2,
2,
3
]
}
],
"ok" : 1
}
對於您的實際形式,因此假設您實際上知道“類型”的可能值,則可以通過兩個$group
階段和$cond
運算符的一些使用來實現:
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
階段的動態表單:
db.types.aggregate([
{ "$group": {
"_id": {
"stat": "$stat",
"type": "$type"
},
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": "$_id.stat",
"types": { "$push": {
"type": "$_id.type",
"count": "$count"
}}
}}
])
輸出結果不同,但功能和值靈活:
{
"_id" : "foobar",
"types" : [
{
"type" : 3,
"count" : 1
},
{
"type" : 2,
"count" : 1
},
{
"type" : 1,
"count" : 2
}
]
}
否則,如果您需要相同的輸出格式但需要靈活的字段,則可以始終使用mapReduce,但它並不完全相同。
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樣式:
"results" : [
{
"_id" : "foobar",
"value" : {
"type1" : 2,
"type2" : 1,
"type3" : 1
}
}
],
但這是您的選擇
這樣夠近嗎?
{ "_id" : "foobar", "types" : [ { "type" : "type3", "total" : 1 }, { "type" : "type2", "total" : 1 }, { "type" : "type1", "total" : 2 } ] }
這些類型位於數組中,但似乎可以為您提供所需的數據。 代碼是:
db.types.aggregate(
[{$group : {
_id : "$stat",
types : {$push : "$type"}
}},
{$unwind:"$types"},
{$group: {
_id:{stat:"$_id",
types: {$substr: ["$types", 0, 1]}},
total:{$sum:1}}},
{$project: {
_id:0,
stat:"$_id.stat",
type: { $concat: [ "type", "$_id.types" ] },
total:"$total" }},
{$group: {
_id: "$stat",
types: { $push: { type: "$type", total: "$total" } } }}
]
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.