Mongo聚合由一个数组元素组成

时间:2014-09-08 15:08:57

标签: mongodb aggregation-framework

我有以下文件:

{
  "_id" : ObjectId("540dadfcf3116b60d401c314"),
  "value" : 2,
  "d_c_at" : [
    "2013",
    "201311",
    "2013w46",
    "20131116"
  ]
}

我希望按d_c_at数组中的最后一个元素(20131116)对它们进行分组,这些元素将年,月,日商店表示为结构化日期。

这是我到目前为止所做的:

db.points.aggregate(
  { $match: { "d_c_at.0": '2014' } },
  { $group: { _id: "$d_c_at.0", value: { $sum: "$value" } } }
)

返回:

{ "_id" : [ ], "value" : 1207 }

我尝试使用$unwind但没有成功:

db.points.aggregate(
  { $match: { "d_c_at.0": '2014' } },
  { $unwind: "$d_c_at" },
  { $group: { _id: "$d_c_at", value: { $sum: "$value" } } }
)

看起来几乎不错,但它也在其他数组元素上分组:

{ ... }
{ "_id" : "20140519", "value" : 33 }
{ "_id" : "20140707", "value" : 36 }
{ "_id" : "20140330", "value" : 37 }
{ "_id" : "20140709", "value" : -28 }
{ "_id" : "20140620", "value" : 14 }
{ "_id" : "2014w9", "value" : -250 }
{ ... }

预期产出:

{ ... }
{ "_id" : "20140519", "value" : 33 }
{ "_id" : "20140707", "value" : 36 }
{ "_id" : "20140330", "value" : 37 }
{ "_id" : "20140709", "value" : -28 }
{ "_id" : "20140620", "value" : 14 }
{ ... }

1 个答案:

答案 0 :(得分:3)

虽然使用聚合可以实现这一点,但使用Map-reduce可以轻松实现预期输出: 假设您的d_c_at,总是有4个元素,或者第4个元素是您的组ID标准,正如您的示例结构所示。

将键作为第4个元素发出,以便文档按“d_c_at”的第4个元素分组。

var map = function(){emit(this.d_c_at[3],{"sum":this.value});} 

完成后,计算总和:

var reduce = function(id,Arr){
var sum = 0;
for(var i=0;i<Arr.length;i++)
    {
        var obj = Arr[i];
        var value = obj.sum;
        sum = sum+value;
    }
    return {"sum":sum};
}

将结果转储到“输出”。

db.test.mapReduce(
                     map,
                     reduce,
                     { out: "output" }
                   )

O / P:

> db.output.find()
{ "_id" : "20131116", "value" : { "sum" : 6 } }
{ "_id" : "20131117", "value" : { "sum" : 6 } }

使用的样本i / p:

{
  "_id" : 1,
  "value" : 2,
  "d_c_at" : [
    "2013",
    "201311",
    "2013w46",
    "20131116"
  ]
}

{
  "_id" : 2,
  "value" : 4,
  "d_c_at" : [
    "2013",
    "201311",
    "2013w46",
    "20131116"
  ]
}

{
  "_id" : 3,
  "value" : 6,
  "d_c_at" : [
    "2013",
    "201311",
    "2013w46",
    "20131116"
  ]
}