【问题标题】:mongo db map reduce sum results as integermongodb map将总和结果减少为整数
【发布时间】:2013-05-29 15:09:26
【问题描述】:

我的收藏是这样的

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

使用上面的数据 我需要计算玩家总胜数

我的 map reduce 函数在这里:

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)" 
}

我猜我的 map reduce 函数是正确的,但我需要将值项求和为整数。 我还尝试了 parseInt() 和 new NumberLong() 函数。

【问题讨论】:

  • 我不确定我是否理解,您的结果中的“红色”、“奇数”和“偶数”来自哪里?你想要的结果是什么?按项目分组的总获胜次数?
  • 我猜这些来自 OP 的原始数据集?反正这是我的猜测 - 跟踪投注 + 'red'、'odd'、'even' ==> 轮盘赌? :)
  • @Joackim,item 可以是 "item": "x14" 或 "item": "red" 没关系,这只是一个示例。我需要按项目分组。

标签: mongodb mongodb-query


【解决方案1】:

以下对我有用:

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

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

结果相同,类型保留,速度也更快。

【讨论】:

  • 谢谢 .. :) 聚合正常,但 map reduce 仍然无法正常工作。 这是您的 numberInt() 的结果解决方案。 结果 { "_id": "x1", "value": NumberInt(0) } { "_id": "x0", "value": "00,0" } { "_id": " red", "value": "00,0,20,50,20,20,20,100,0,20,20,0,0,20,100" }
  • 那是因为你的reduce函数不正确。您正在将值添加到 sum,但 values 是一个数组 - 您需要将其中的所有内容相加(并添加到 sum)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-19
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
相关资源
最近更新 更多