No commit activity in last 3 years
No release in over 3 years
Reduce load from your application server by offloading indexing into background jobs
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

>= 5.0.0
 Project Readme

Elasticsearch::Model::TransactionalCallbacks

Gem Version CircleCI Maintainability

The elasticsearch-model works great in simplifying the integration of Ruby classes ("models") with the Elasticsearch search and analytics engine. But, it come short with support for updating the indexed documents asynchronously.

Built-in support for updating the indexed documents comes in the form of Elasticsearch::Model::Callbacks which will update each related document individually inside the same thread where the changes were made. Depending on the size of your application, and the size of the changes themselves, triggering N number of indexing requests to Elasticsearch could amount to nothing, or it could slow down the request-response cycle considerably and render it unusable.

This gem aims to solve this by providing a way to update the index asynchronously via ActiveJob.

Usage

The minimum is to include Elasticsearch::Model::TransactionalCallbacks into any model which could benefit from asynchronous indexing, e.g.

class User < ApplicationRecord
  include Elasticsearch::Model
  include Elasticsearch::Model::TransactionalCallbacks

  index_name 'users'
  document_type 'user'

  mappings do
    # indexes for users
  end
end

But, this will end up trading n+1 on updating index with n+1 on database queries in case your #as_indexed_json pulls data from associated models, e.g.

class Post < ApplicationRecord
  include Elasticsearch::Model
  include Elasticsearch::Model::TransactionalCallbacks

  has_many :taggings, as: :taggable
  has_many :tags, through: :taggings

  index_name 'posts'
  document_type 'post'

  mappings dynamic: false do
    indexes :subject, type: 'text', analyzer: 'english'
    indexes :tags, type: 'keyword'
  end

  def as_indexed_json(_options = {})
    {
      subject: subject,
      tags: tags.map(&:key) # FIXME: this triggers n+1 queries
    }
  end
end

to get around this, you can define a scope called preload_for_import like so:

class Post < ApplicationRecord
  # ...snip...
  scope :preload_for_import, -> { preload(:tags) }
  # ...snip...
end

and it will be automatically called by the library.

Compatibility

This library is compatible and tested with Elasticsearch 5. Some work might be needed to make it work with Elasticsearch 6.

Installation

Add this line to your application's Gemfile:

gem 'elasticsearch-model-transactional_callbacks'

And then execute:

$ bundle

Or install it yourself as:

$ gem install elasticsearch-model-transactional_callbacks

Contributing

Any and all kinds of help are welcome! Especially interested in:

  • sample use cases which are not yet supported
  • compatibility with elasticsearch 6.0

Feel free to file an issue/PR with sample mapping!

License

The gem is available as open source under the terms of the MIT License.