【问题标题】:mongodb group and sum?mongodb组和总和?
【发布时间】:2014-06-08 01:21:03
【问题描述】:

在过去的几个小时里,我一直在纠结这个问题,无法解决这个问题。也许有人可以帮忙。我有一个包含以下内容的集合。

{
    "smallparts": [
        { "quantity": "10", "part": "test1" },
        { "quantity": "10", "part": "test2" }
    ]
},
{
    "smallparts": [
        { "quantity": "10", "part": "test3" }
    ]
},
{
    "smallparts": [
        { "quantity": "10", "part": "test1" },
        { "quantity": "10", "part": "test2" }
    ]
}

当尝试以下添加数量时,我无法正确。

collection.aggregate(    

    // Unwind the array
    { "$unwind":"$smallparts" },

    // Group the products
    {
      "$group":
      {
         "_id":
         {
            "part": "$smallparts.part",
            "total": "$smallparts.quantity",
         }
      },
   },

我的输出是错误的。 test1 和 test2 应该是 20。

{
"data": [
    {
        "_id": {
            "part": "test3",
            "total": "10"
        }
    },
    {
        "_id": {
            "part": "test2",
            "total": "10"
        }
    },
    {
        "_id": {
            "part": "test1",
            "total": "10"
        }
    }
]

}

我也试过了,但得到一个空数组。

collection.aggregate(
//展开数组 { "$unwind":"$smallparts" },

// Group the products
{
  "$group":
  {
     "_id":
     {
        "part": "$smallparts.part",
        "total": "$smallparts.quantity",
         sum: { $sum: "$smallparts.quantity" }
     }
  },

感谢您的帮助。

【问题讨论】:

    标签: javascript node.js mongodb


    【解决方案1】:

    您面临的问题是您不能将$sum 与字符串一起使用。您需要将数量转换为整数才能使此查询起作用。

    数量为整数时,按部分分组的总和的方法:

    db.coll.aggregate([
        { $unwind : "$smallparts"},
        { $group : { 
            _id : "$smallparts.part" , 
             sum :  { $sum : "$smallparts.quantity" } 
        } 
    }]);
    

    如果您可以控制 db 架构,这将是推荐的方法。

    第二种方法是使用 map-reduce 重写查询,您可以使用 parseInt 等 JavaScript 函数来转换值:

    var mapFunction = function() {
        for (var idx = 0; idx < this.smallparts.length; idx++) {
            emit(this.smallparts[idx].part, this.smallparts[idx].quantity);
        }
    };
    
    var reduceFunction = function(key, vals) {
        var sum = 0;
        for (var idx = 0; idx < vals.length; idx++) {
            sum += parseInt(vals[idx]);
        }
        return sum;
    };
    
    db.coll.mapReduce(mapFunction, reduceFunction, { out : "my_mapreduce_res"});
    

    您的 map-reduce 结果将存储在 my_mapreduce_res 集合中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多