DEPRECATED - Consider using SearchKick


Build Status Coverage Status Gem Version Dependency Status Issues License

Use Elasticsearch with mongoid with just a few lines of code

Allows easy usage of the new Elasticsearch gem with Mongoid 4


  • Uses new elasticsearch gem
  • Has a simple high-level API
  • No weird undocumented DSL, just raw JSON for queries and index definitions
  • Allows for full power of elasticsearch when it's necessary
  • Indexes are automatically created if they don't exist on app boot
  • Works out of the box with zero configuration
  • Multi-model search with real model instances and pagination
  • Whole test suite is run against a real ES instance, no mocks

This gem is very simple and does not try hide any part of the ES REST api, it just adds some shortcuts for prefixing index names, automatic updating of the index when models are added\changed, search with pagination, wrapping results in a model instance, ES 0.90.3 new completion suggester, etc (new features coming soon)

Alternatives list:


Add this line to your application's Gemfile:

gem 'mongoid-elasticsearch'

And then execute:

$ bundle

Or install it yourself as:

$ gem install mongoid-elasticsearch



class Post
  include Mongoid::Document
  include Mongoid::Elasticsearch
end 'test text' # shortcut for{q: 'test text'})
result = body: {query: {...}, facets: {...}} etc
result.results # by default returns an Enumerable with Post instances exactly
               # like they were loaded from MongoDB # create index (done automatically on app boot) # drop index # recreate index # force index update (useful for specs) # Elasticsearch::Client instance


include Mongoid::Elasticsearch
elasticsearch! index_mappings: {
  name: {
    type: 'multi_field',
    fields: {
      name: {type: 'string', boost: 10},
      suggest: {type: 'completion'}
  desc: {type: 'string'},
}'te', 'name.suggest') # requires ES 0.90.3

Search multiple models:

# By default only searches in indexes managed by Mongoid::Elasticsearch
# to ignore other apps indexes in same ES instance
response = 'test'

search syntax docs:

ES Actions docs:

ES Indices docs:

ES docs:


prefix all app's index names:

Mongoid::Elasticsearch.prefix = 'my_app'

default options for (url etc)

Mongoid::Elasticsearch.client_options = {hosts: ['localhost']}

index definition options and custom model serialization:

include Mongoid::Elasticsearch
  # index name (prefix is added)
  index_name: 'mongoid_es_news',

  # don't use global name prefix
  prefix_name: false,

  # elasticsearch index definition
  index_options: {},

  # or only mappings with empty options
  index_mappings: {
    name: {
      type: 'multi_field',
      fields: {
        name:     {type: 'string', analyzer: 'snowball'},
        raw:      {type: 'string', index: :not_analyzed},
        suggest:  {type: 'completion'} 
    tags: {type: 'string', include_in_all: false}
  wrapper: :load

# customize what gets sent to elasticsearch:
def as_indexed_json
  # id field is properly added automatically
    name: name,
    excerpt: excerpt
  # mongoid_slug note: add _slugs to as_indexed_json, NOT slug

Example mapping with boost field:

  index_name: Rails.env.test? ? 'vv_test_articles' : 'vv_articles',
  index_options: {
    settings: {
      index: {
        analysis: {
          analyzer: {
            my_analyzer: {
              type: "snowball",
              language: "Russian"
    mappings: {
      "articles/article" => {
        _boost: {name: '_boost', null_value: 1},
        properties: {
          name: {type: 'string', boost: 10, analyzer: 'my_analyzer'},
          tags: {type: 'string', analyzer: 'my_analyzer'}
  wrapper: :load

Mapping definition docs


= paginate @posts should work as normal with Kaminari after you do:

@posts =[:search], page: params[:page])
# or
@posts ={
  body: {
    query: {
      query_string: {
        query: params[:search]
    filter: {
      term: {community_id:}
  page: params[:page], wrapper: :load


All models

rake es:reindex will reindex all indices managed by Mongoid::Elasticsearch

One model - Simple bulk

This is the preferred (fastest) method to reindex everything

One model - Simple
Communities::Thread.enabled.each do |ingr|

Possible wrappers for results:

  • :hash - raw hash from ES
  • :mash - Hashie::Mash (gem 'hashie' must be added to gemfile)
  • :load - load each found model by ID from database
  • :model - create a model instance from data stored in elasticsearch

See more examples in specs.

Index creation

This gem by default automatically creates indexes for all configured models on application startup.

Set Mongoid::Elasticsearch.autocreate_indexes = false in an initalizer to prevent automatic creation for all indexes.

You can always use rake es:create to create all indexes or call Mongoid::Elasticsearch.create_all_indexes!.

Indexes defined with option skip_create: true are not created with all other indexes and must be created manually with


# Escape string so it can be safely passed to ES (removes all special characters)


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request