0

My collections seems like this

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

using above the data i need to calculate player total wins

and My map reduce functions is here :

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

i guess my map reduce functions is correct but i need to sum value items as integer. i also tried to parseInt() and new NumberLong() functions.

Ersin Güvenç
  • 93
  • 1
  • 14
  • I'm not sure I understand, where are the "red", "odd" and "even" coming from in your result? What is your desired result? Total wins grouped by item? – Joachim Isaksson May 29 '13 at 15:44
  • I'm guessing those are from OP's original data set? That was my guess anyway - tracking betting + 'red', 'odd', 'even' ==> roulette? :) – Asya Kamsky May 29 '13 at 16:12
  • @Joackim, item can be "item": "x14", or "item": "red" doesn't matter this just an an example.I need to group by item. – Ersin Güvenç May 31 '13 at 07:21

1 Answers1

2

The following works for me:

In your map function change your emit to

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

In your reduce change sum to be:

var sum = NumberInt(0);

Now testing it:

> 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 (Hex 10) is the type for 32-bit integer in bson.

If your number of items being aggregated is not too large, I would recommend looking at using aggregation framework:

> 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

Same result, type preserved, and faster too.

Asya Kamsky
  • 41,784
  • 5
  • 109
  • 133
  • **Thanks .. :)** **aggregate ok but map reduce still does not work well.** **This is the results of your numberInt() solution.** results { "_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" } – Ersin Güvenç May 31 '13 at 08:12
  • That's because your reduce function is incorrect. You are adding values to sum, but values is an array - you need to add everything in it together (and add to sum). – Asya Kamsky May 31 '13 at 08:16