2014-06-07 193 views
1

在过去的几个小时里,我一直在碰撞着这个东西,不能把头绕在里面。也许有人可以帮忙。我收集了以下内容。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(
//放松阵列 { “$开卷”: “$ smallparts”},

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

感谢您的帮助

回答

2

问题你所面对的是你不能使用$sum和字符串,你需要将你的数量转换为整数才能使这个查询正常工作

获得所有总的分组的总和一部分,当数量为整数的方式:

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

如果你有在DB模式控制,这将是推荐的方法。

第二种方法是使用来重写查询地图,减少在那里你可以使用JavaScript功能,如parseInt将值转换:

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收藏。