MongoDB:聚合特定子文档的所有字段的值

时间:2015-04-24 07:04:35

标签: mongodb aggregation-framework

我正在尝试使用MongoDB的聚合框架从具有以下结构的集合生成文档:

{
  "_id" : ObjectId("5510eb56f877bbef153d236d"),
  "attributes" : {
    "brand" : "Mercedes",
    "price" : 289,
    "family" : "GARDEN"
  },
  "name" : "Bigger Fix Soft Crisps"
}
{
  "_id" : ObjectId("5510eb56f877bbef153d236e"),
  "attributes" : {
    "brand" : "Adelholzener",
    "price" : 683,
    "family" : "COMPUTER"
  },
  "name" : "Soft Stockhome Chips"
}
{
  "_id" : ObjectId("5510eb56f877bbef153d236f"),
  "attributes" : {
    "brand" : "Pepsi",
    "price" : 789,
    "family" : "CAR"
  },
  "name" : "Light Yearsailfresh Meat"
}

我想从attributes子文档中获取所有字段的聚合及其可能的值。由于子文档中的字段未知,因此我不能简单地使用此示例中给出的字段,因此必须是动态的。结果看起来应该类似于:

{
  "_id" : "brand",
  "values" : [
    "Mercedes", "Adelholzener", "Pepsi"
  ]
},
{
  "_id" : "price",
  "values" : [
    289, 683, 789
  ]
},
{
  "_id" : "family",
  "values" : [
    "GARDEN", "COMPUTER", "CAR"
  ]
}

到目前为止,我还没有找到解决这个特殊问题的方法。我尝试使用$project$unwind(显然这只适用于数组)。

1 个答案:

答案 0 :(得分:1)

试图找出如何做到聚合,但我不确定它是否可能,因为你无法以任何好的方式获取对象中的键。

这是一个执行该操作的MapReduce作业:

db.runCommand({
  "mapreduce" : "test_collection", // Change collection here
  "map" : function() {
    for (var key in this.attributes) {
      // Emit objects w array as we cannot reduce arrays directly
      emit(key, {x: [this.attributes[key]]});
    }
  },
  "reduce" : function(key, values) { 
    var res = [];
    values.forEach(function (d) {
      Array.prototype.push.apply(res, d.x);         
    });
    return {x: res};
  }, 
  "finalize": function (key, reducedVal) {
    return reducedVal.x;
  },
  "out": { inline: 1 }
});