module Elasticsearch::Model::Indexing::InstanceMethods

Public Class Methods

included(base) click to toggle source
# File lib/elasticsearch/model/indexing.rb, line 332
def self.included(base)
  # Register callback for storing changed attributes for models
  # which implement `before_save` and return changed attributes
  # (ie. when `Elasticsearch::Model` is included)
  #
  # @note This is typically triggered only when the module would be
  #       included in the model directly, not within the proxy.
  #
  # @see #update_document
  #
  base.before_save do |obj|
    if obj.respond_to?(:changes_to_save) # Rails 5.1
      changes_to_save = obj.changes_to_save
    elsif obj.respond_to?(:changes)
      changes_to_save = obj.changes
    end

    if changes_to_save
      attrs = obj.instance_variable_get(:@__changed_model_attributes) || {}
      latest_changes = changes_to_save.inject({}) { |latest_changes, (k, v)| latest_changes.merge!(k => v.last) }
      obj.instance_variable_set(:@__changed_model_attributes, attrs.merge(latest_changes))
    end
  end if base.respond_to?(:before_save)
end

Public Instance Methods

delete_document(options = {}) click to toggle source

Deletes the model instance from the index

@param options [Hash] Optional arguments for passing to the client

@example Delete a record

@article.__elasticsearch__.delete_document
2013-11-20 16:27:00 +0100: DELETE http://localhost:9200/articles/article/1

@return [Hash] The response from Elasticsearch

@see rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions:delete

# File lib/elasticsearch/model/indexing.rb, line 394
def delete_document(options = {})
  request = { index: index_name,
              id: self.id }
  request.merge!(type: document_type) if document_type

  client.delete(request.merge!(options))
end
index_document(options = {}) click to toggle source

Serializes the model instance into JSON (by calling ‘as_indexed_json`), and saves the document into the Elasticsearch index.

@param options [Hash] Optional arguments for passing to the client

@example Index a record

@article.__elasticsearch__.index_document
2013-11-20 16:25:57 +0100: PUT http://localhost:9200/articles/article/1 ...

@return [Hash] The response from Elasticsearch

@see rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions:index

# File lib/elasticsearch/model/indexing.rb, line 371
def index_document(options = {})
  document = as_indexed_json
  request = { index: index_name,
              id: id,
              body: document }
  request.merge!(type: document_type) if document_type

  client.index(request.merge!(options))
end
update_document(options = {}) click to toggle source

Tries to gather the changed attributes of a model instance (via [ActiveModel::Dirty](api.rubyonrails.org/classes/ActiveModel/Dirty.html)), performing a partial update of the document.

When the changed attributes are not available, performs full re-index of the record.

See the {#update_document_attributes} method for updating specific attributes directly.

@param options [Hash] Optional arguments for passing to the client

@example Update a document corresponding to the record

@article = Article.first
@article.update_attribute :title, 'Updated'
# SQL (0.3ms)  UPDATE "articles" SET "title" = ?...

@article.__elasticsearch__.update_document
# 2013-11-20 17:00:05 +0100: POST http://localhost:9200/articles/article/1/_update ...
# 2013-11-20 17:00:05 +0100: > {"doc":{"title":"Updated"}}

@return [Hash] The response from Elasticsearch

@see rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions:update

# File lib/elasticsearch/model/indexing.rb, line 426
def update_document(options = {})
  if attributes_in_database = self.instance_variable_get(:@__changed_model_attributes).presence
    attributes = if respond_to?(:as_indexed_json)
        self.as_indexed_json.select { |k, v| attributes_in_database.keys.map(&:to_s).include? k.to_s }
      else
        attributes_in_database
      end

    unless attributes.empty?
      request = { index: index_name,
                  id: self.id,
                  body: { doc: attributes } }
      request.merge!(type: document_type) if document_type

      client.update(request.merge!(options))
    end
  else
    index_document(options)
  end
end
update_document_attributes(attributes, options = {}) click to toggle source

Perform a partial update of specific document attributes (without consideration for changed attributes as in {#update_document})

@param attributes [Hash] Attributes to be updated @param options [Hash] Optional arguments for passing to the client

@example Update the ‘title` attribute

@article = Article.first
@article.title = "New title"
@article.__elasticsearch__.update_document_attributes title: "New title"

@return [Hash] The response from Elasticsearch

# File lib/elasticsearch/model/indexing.rb, line 461
def update_document_attributes(attributes, options = {})
  request = { index: index_name,
              id: self.id,
              body: { doc: attributes } }
  request.merge!(type: document_type) if document_type

  client.update(request.merge!(options))
end