mongodb组和总和?

时间:2014-06-07 07:06:17

标签: javascript node.js mongodb

过去几个小时我一直在摸着头,无法绕过它。也许有人可以帮忙。我有一个以下的集合。

{
    "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" }
     }
  },

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您遇到的问题是您不能将$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"});

您的地图缩减结果将存储在my_mapreduce_res集合中。