mongo db map将sum结果减少为整数

时间:2013-05-29 15:09:27

标签: mongodb mongodb-query

我的收藏品似乎是这样的

{
"bet_session_id": ObjectId("51a60cba6ef215d019000299"),
"date": ISODate("2013-05-29T14:13:14.572Z"),
"player_items": [
{
  "chip": NumberInt(1),
  "item": "x14",
  "ratio": NumberInt(35),
  "total_win": NumberInt(0)
},
{
  "chip": NumberInt(1),
  "item": "x15",
  "ratio": NumberInt(35),
  "total_win": NumberInt(36)
},
{
  "chip": NumberInt(1),
  "item": "121511141013",
  "ratio": NumberInt(5),
  "total_win": NumberInt(6)
},
],
"user_id": "7876010",
}
,
{
"bet_session_id": ObjectId("51a60cba6ef215d019000299"),
"date": ISODate("2013-05-29T14:13:14.572Z"),
"player_items": [
{
  "chip": NumberInt(1),
  "item": "x14",
  "ratio": NumberInt(35),
  "total_win": NumberInt(0)
},
{
  "chip": NumberInt(1),
  "item": "x15",
  "ratio": NumberInt(35),
  "total_win": NumberInt(36)
},
{
  "chip": NumberInt(1),
  "item": "121511141013",
  "ratio": NumberInt(5),
  "total_win": NumberInt(6)
},
{
  "chip": NumberInt(1),
  "item": "12151114",
  "ratio": NumberInt(8),
  "total_win": NumberInt(9)
},
{
  "chip": NumberInt(1),
  "item": "1514",
  "ratio": NumberInt(17),
  "total_win": NumberInt(18)
},
{
  "chip": NumberInt(1),
  "item": "1215",
  "ratio": NumberInt(17),
  "total_win": NumberInt(18)
},
{
  "chip": NumberInt(1),
  "item": "151814171316",
  "ratio": NumberInt(5),
  "total_win": NumberInt(6)
},
{
  "chip": NumberInt(1),
  "item": "151413",
  "ratio": NumberInt(11),
  "total_win": NumberInt(12)
},
{
  "chip": NumberInt(1),
  "item": "15181417",
  "ratio": NumberInt(8),
  "total_win": NumberInt(9)
}
],
"user_id": "9034906623",
}

使用上面的数据 我需要计算球员总赢数

和我的地图缩减功能在这里:

var mapBetPlayWinStats = function() { 
for (i=0; i<this.player_items.length; i++ ) emit( this.player_items[i].item, this.player_items[i].total_win )};

var reduceBetPlayWinStats = "function(item,values) { var sum = 0; sum += values; return sum; }"

db.bet_results.mapReduce(mapBetPlayWinStats, reduceBetPlayWinStats, {out: "bet_number_play_win_stats"});

RESULTS:
{
"_id": "red",
"value": "20,50,20,NumberLong(20),NumberLong(20),100" 
}
{
"_id": "odd",
"value": "NumberLong(0),NumberLong(0)" 
}
{
"_id": "even",
"value": "0,20,NumberLong(20),NumberLong(20)" 
}

我想我的地图缩小功能是正确的,但我需要将值项目作为整数求和。 我还尝试了parseInt()和新的NumberLong()函数。

1 个答案:

答案 0 :(得分:2)

以下适用于我:

在地图功能中,将发射更改为

emit( this.player_items[i].item, NumberInt(this.player_items[i].total_win) )};

在你的减少变化总和为:

var sum = NumberInt(0);

现在测试一下:

> db.bet_number_play_win_stats.find({value:{$type:16}})
{ "_id" : "121511141013", "value" : 6 }
{ "_id" : "x14", "value" : 0 }
{ "_id" : "x15", "value" : 36 }
Fetched 3 record(s) in 1ms

16(十六进制10)是type for 32-bit integer in bson

如果您聚合的项目数量不是太大,我建议您考虑使用聚合框架:

> var r=db.bet_results.aggregate( [
             {$unwind : "$player_items"}, 
             {$group: { _id:"$player_items.item", 
                        wins:{$sum:"$player_items.total_win"}
                      }
              }
 ] )
> db.bet_number_play_win_agg.save(r.result)
Inserted 1 record(s) in 7ms
> > db.bet_number_play_win_agg.find({wins:{$type:16}})
{ "_id" : "121511141013", "wins" : 6 }
{ "_id" : "x15", "wins" : 36 }
{ "_id" : "x14", "wins" : 0 }
Fetched 3 record(s) in 1ms

同样的结果,类型保留,也更快。