MongoDB - 内部和对象的聚合字段

时间:2016-06-09 13:35:39

标签: mongodb aggregation-framework

我在MongoDB中有以下数据集:

{
  _id: 574718ec2bc91f565db33897,
  topic: {
    T69: 0.9566255761668587
  }
},
{
  _id: 574718ec2bc91f565db33899,
  topic: {
    T257: 0.046038051058499445,
    T2: 1.8206715756325407,
    T31: 0.08838710118945285
  }
},
{
  _id: 574718ec2bc91f565db33889,
  topic: {
    T95: 0.37718859499517865,
    T40: 0.2620479937270479,
    T2: 0.3594989449758472,
    T1: 1.9161288780994465
  }
}

我一直在尝试创建一个聚合查询,它在所有这些文档的集合中返回所有主题的总和Tn。任何人都可以给我指向正确的方向吗?由于我是MongoDB的新手,我无法找到这个问题的答案(虽然这似乎与$unwind an object in aggregation framework相关)。

2 个答案:

答案 0 :(得分:0)

我认为你不能用mongoDB聚合框架(对于subdocs的集合/数组更好地工作),但是使用map / reduce非常简单。例如,您可以尝试:

db.YOURCOLLECTION.mapReduce(
  function () {
    var topic = this.topic;
    Object.keys(topic).forEach(function(k) {
      emit(k, topic[k]);
    });
  },
  function (key, values) {
     return Array.sum(values);
  }
);

答案 1 :(得分:0)

我们最好的选择是mapReduce。在我们的map函数中,我们所需要的只是迭代"主题"属性并发出值。要获得集合中的总和,我们需要"发出"以null为关键值。

在reduce函数中,我们只需使用Array.sum方法返回总和。

db.coll.mapReduce(function() { 
    for (var key in this.topic) { 
        if (Object.prototype.hasOwnProperty.call(this.topic, key)) {
            emit(null, this.topic[key]) 
        }
    }}, 
    function(key, value) { 
        return Array.sum(value);
    }, 
    { "out": { "inline": 1 } }
)

产生:

{
    "results" : [
        {
            "_id" : null,
            "value" : 5.826586715844872
        }
    ],
    "timeMillis" : 26,
    "counts" : {
        "input" : 3,
        "emit" : 8,
        "reduce" : 1,
        "output" : 1
    },
    "ok" : 1
}

如果你想要"总和"对于每个文档,只需在地图函数中调用emit(this._id, this.topic[key])而不是emit(null, this.topic[key])