indexing

You can define indexes on documents using the index macro. For unique indexes provide a unique options, otherwise no option is necessary.

class Person
  include Mongoid::Document
  field :ssn
  index :ssn, unique: true
end

You can define indexes on embedded document fields as well.

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

You can index on multiple fields and provide direction.

class Person
  include Mongoid::Document
  field :first_name
  field :last_name
  index(
    [
      [ :first_name, Mongo::ASCENDING ],
      [ :last_name, Mongo::ASCENDING ]
    ],
    unique: true
  )
end

Indexes can be sparse:

class Person
  include Mongoid::Document
  field :ssn
  index :ssn, sparse: true
end

Indexes can be run in the background in cases where they may take some time:

class Person
  include Mongoid::Document
  field :ssn
  index :ssn, unique: true, background: true
end

For geospacial indexes, make sure the field you are indexing is an Array.

class Person
  include Mongoid::Document
  field :location, type: Array
  index [[ :location, Mongo::GEO2D ]], min: 200, max: 200
end

You can have Mongoid define indexes for you on "foreign key" fields for relational associations. This only works on the relation macro that the foreign key is stored on.

class Comment
  include Mongoid::Document
  belongs_to :post, index: true
  has_and_belongs_to_many :preferences, index: true
end

When you want to create the indexes in the database, use the provided rake task.

rake db:mongoid:create_indexes

Note that you must following standard Rails class and module naming and organization patterns in order for this to work properly with respect to namespacing and camel-casing.

Model # must reside in /app/models/model.rb
MyModel # must be in /app/models/my_model.rb
MYModel # must be in /app/models/m_y_model.rb
Namespaced::Model # must be in /app/models/namespaced/model.rb

If you want indexes autocreated when the model classes are loaded, add this configuration option to your mongoid.yml. Note this is NOT recommended for any production environment.

defaults: &defaults
  autocreate_indexes: true

dropping indexes

When you want to remove an index, it must be done using the MongoDB index name. Therefore if you create a range index on the birthday date coluumn in the Person model in the Rails console, you would do it like this.

:001 > Person.collection.ensure_index([['birthday',Mongo::DESCENDING]])

In order to delete that same index, you need to use the index name, not the index definition. The index name is birthday, but the index definition according to MongoDB will include an _1 for an Mongo::ASCENDING range index and a _-1 for a Mongo::DESCENDING range index. To remove the above index in the Rails console, you would enter the following.

:002 > Person.collection.drop_index('birthday_-1')