在任意数量的不同键上查找聚合

时间:2016-09-21 06:10:01

标签: mongodb mongoose aggregation-framework

我在mongoDB中有一个看起来像

的集合
 collection:

   doc1
    { field1 : {
            field1_1 : 'val1',
            field1_2 : 'val2',
            field1_3 : 'val3',
            ...
            field1_N : 'valN' } }

   doc2
    { field1 : {
            field1_1 : 'val1',
            field1_2 : 'val2',
            field1_3 : 'val3',
            ...
            field1_N : 'valN' } }

我想在val1, val2, val3 ... valN上找到聚合(sum,avg,min,max)。有没有办法使用mongo的聚合功能?密钥总是不同的,聚合应该发生在field1

的所有值上

编辑:

最终输出应该如下,

   doc1
    { field1 : {
            sum: sumOf(val1, val2... valN),
            avg: avgOf(val1, val2... valN)
            ... } }

   doc2
    { field1 : {
            sum: sumOf(val1, val2... valN),
            avg: avgOf(val1, val2... valN)
            ... } }

3 个答案:

答案 0 :(得分:1)

可以根据您的要求使用Map-Reduce而非聚合来尝试此操作。 map-reduce操作提供了聚合管道中目前不可用的一些灵活性。

var mapFunction = 
  function() {
    for (key in this.field1) {
      emit(this._id, parseInt(this.field1[key]));
    }
  };

  var reduceFunction = 
  function(key, values) {
    return {sum:Array.sum(values), avg:Array.avg(values)};
  };

db.getCollection('collectionName').mapReduce(mapFunction, reduceFunction, {out: {inline:1}});

据我所知,您的文档结构是否类似:

field1 : [
            {field1 : 'val1'},
            {field1 : 'val2'},
            {field1 : 'val3'},
            ...
            {field1 : 'valN'}]

然后您可以使用aggregate轻松解决。所以对于你的结构mapReducemay更好。

答案 1 :(得分:0)

你可以尝试$ sum用于sum和$ multiply用于乘法..你可以在以下链接找到MongoDb可用的所有聚合函数: https://docs.mongodb.com/manual/reference/operator/aggregation/sum/

希望这会有所帮助..

答案 2 :(得分:0)

我不是一个mongodb忍者,但我有一个解决你问题的方法。它不是最有效的,但如果你被困在王室,你可以使用它。

所以下面的代码创建了一个投影,你想要聚合(avg)的字段的avg数据,这是你必须指定每个字段,而不是一种迭代的方式通过所有领域和聚合。你绝对可以使用JS进行迭代,过去我曾经简要地介绍过它,但是我可能需要稍微调整一下,而不是我在下面提供的代码。

另外,我假设,field1.field1_1:“int”。是整数而不是字符串值。

db.random.aggregate(
    [
        {
            $project:
            {
                _id: "$field1",
                avgAmount: { $avg: ["$field1.field1_1", "$field1.field1_2", "$field1.field1.3"]}
            }
        }]
) 

祝你好运#lolo。