2

I've read the mongoid docs, but don't feel confident I properly understand how to index embedded documents correctly. Please take a look at this tiny code snippet and let me know if I am on the right track!

Criteria

temp = Array.new
temp.push(BSON::ObjectId("some_bson_objecId"))
temp.push(BSON::ObjectId("some_other_bson_objecId"))
Game.any_of({'players.user_id' => @user.id},{:_id => temp})

Game model

embeds_many :players
index(
[
  [ "players.user_id" ],
  [ "players.user_name" ]
],
unique: true
)

Player model

embedded_in :game
field :user_id, :type => BSON::ObjectId
field :user_name, :type => String, :default => ""
index(
[
  [ :user_id ],
  [ :user_name ]
],
unique: true
)
hcon
  • 21
  • 4

2 Answers2

0

From Mongoid's Docs -

class Person
  include Mongoid::Document
  embeds_many :addresses
  index "addresses.street" => 1
end

so try

class Game 
  include Mongoid::Document
  embeds_many :players 
  index "players.user_id" => 1
  index "players.user_name" => 1
end

class Player
  include Mongoid::Document
  embedded_in :game
  field :user_id
  field :user_name
  index({ user_id: 1, user_name: 1 })
end
Theta
  • 175
  • 8
0

There is a couple of things you're missing.

  • You need to specify the direction to index each field that you've chosen (the reason explained here.)

  • You're not passing in your arguments to the index method correctly. Instead, the first argument should be a hash of the fields you'd like to index and the second argument should be a hash of options.

The proper syntax for what your code is trying to achieve is this:

Game model

embeds_many :players
index({ 
    "players.user_id" => 1,
    "players.user_name" => 1
  }, {
    unique: true
})

Player model

embedded_in :game
field :user_id, :type => BSON::ObjectId
field :user_name, :type => String, :default => ""
index({
    user_id: 1,
    user_name: 1
  }, {
    unique: true
})

Also, it seems like you are trying to index more than you need to. If you're just going to be searching through the games collection then there is no need to be indexing any of the fields in the Player model.

You should instead just index on the fields that you are going to be querying. In order to properly index the information that you are querying for, your code should look like this:

Game model

embeds_many :players
# The field of the 'games' collection that you will be querying for
index({ "players.user_id" => 1 })

Player model

embedded_in :game
field :user_id, :type => BSON::ObjectId
field :user_name, :type => String, :default => ""
# No indexing necessary for your player model.

More indexing may help if you are performing other queries, but keep in mind that indexing is a trade off of query time for space. MongoDB's website has some guidelines to help you decide whether or not you should index something. Also, remember that you can always query the data without an index, it will just be slower ;).