0

我正在做一个简单的项目,其中有两个示例引用模型:

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

我需要做的是获取与玩家数量有关的顶级游戏列表。与此类似:

{
  "diablo_3": {
    "players": 89
  },
  "max_payne_3": {
    "players": 87
  },
  "world_of_warcraft": {
    "players": 65
  },
  "dirt_3": {
    "players": 43
  }
}

谢谢

4

1 回答 1

1

您可以使用 MongoDB group 命令对单个集合进行一些服务器大小的处理,它可以作为 Ruby 驱动程序中集合的方法使用,请参阅http://api.mongodb.org/ruby/current/Mongo /Collection.html#group-instance_method

请在下面找到基于您的模型的测试,并将标题字段添加到您的游戏模型中。这是使用 MongoDB 的 group 命令对您的问题的有效答案。

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

结果

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
于 2012-05-27T22:24:52.917 回答