Reputation: 1368
I'm working on a simple project where I have two sample referenced models:
class Player
include Mongoid::Document
include Mongoid::Timestamps
has_and_belongs_to_many :games
end
class Game
include Mongoid::Document
include Mongoid::Timestamps
has_and_belongs_to_many :players
end
What I need to do is get a list of top games played with count of players. Similar to this:
{
"diablo_3": {
"players": 89
},
"max_payne_3": {
"players": 87
},
"world_of_warcraft": {
"players": 65
},
"dirt_3": {
"players": 43
}
}
Thanks
Upvotes: 0
Views: 317
Reputation: 3402
You can use the MongoDB group command to do some server-size processing on a single collection, and it is available as a method on the collection in the Ruby driver, see http://api.mongodb.org/ruby/current/Mongo/Collection.html#group-instance_method
Below please find a test based on your models, with the title field added to your Game model. This is a working answer to your question that uses MongoDB's group command.
require 'test_helper'
class GameTest < ActiveSupport::TestCase
def setup
Player.delete_all
Game.delete_all
end
test "game player count" do
input = [ [ 'diablo_3', 89 ], [ 'max_payne_3', 87 ], [ 'world_of_warcraft', 65 ], [ 'dirt_3', 43 ] ]
input.shuffle.each do | title, count |
game = Game.create(title: title)
(0...count).each{ game.players << Player.new }
end
game_player_count = Game.collection.group(key: :_id, cond: {}, initial: {count: 0}, reduce: 'function(doc, out) { out.title = doc.title; out.count = doc.player_ids.length; }')
game_player_count.sort!{|a,b| -(a['count'] <=> b['count']) }
game_player_count = Hash[*game_player_count.map{|r| [r['title'], {"players" => r['count'].to_i} ]}.flatten]
puts JSON.pretty_generate(game_player_count)
end
end
result
Run options: --name=test_game_player_count
# Running tests:
{
"diablo_3": {
"players": 89
},
"max_payne_3": {
"players": 87
},
"world_of_warcraft": {
"players": 65
},
"dirt_3": {
"players": 43
}
}
.
Finished tests in 0.482286s, 2.0735 tests/s, 0.0000 assertions/s.
1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Upvotes: 1