Elastics::ModelSyncer

Notice: Syncing is not needed if you use other external means to sync (like rivers or background jobs).

The Elastics::ModelSyncer model is included in Elastics::ModelIndexer which is included in Elastics::ActiveModel, so they all include the sync-related methods (see Class Methods and Instance Methods). However you may need to explicitly include the Elastics::ModelSyncer (see Including Elastics::ModelSyncer).

Syncing self

Each time you save or destroy a record belonging to a elastics model, you may want to sync the changes with the index. You can implement automatic synchronization by just declaring it. For example:

class Comment
  include Elastics::ModelIndexer
  elastics.sync self
end

That means that each time a Comment record gets saved or destroyed, Elastics will sync self (the Comment instance) with its related elasticsearch document, so the index will always contain the updated data from the DB(s).

Syncing relating models

Sometimes, you may need to sync also other records that are related with the changing record. That is needed when the other record embeds data from the changing record, as in our example with the Parent model (see Indexing Fields). In that case we mapped the indexed source to contain the children.count, so each time we add or remove a Child record, we need also to sync its :parent record (i.e. the self.parent). For example:

class Child
  belongs_to :parent
  include Elastics::ModelIndexer
  elastics.sync self, :parent
end

That means that besides syncing self, Elastics will also sync the :parent parent record.

Propagation

Notice that Elastics calls sync on the synced records as well, so also their defined synced models will be synced as well. This feature automatically propagates the syncronization over models, still keeping its implementation very simple on a per-model basis.

Elastics tracks the propagation, so it avoids circular references. For example you can sync both the parent from the child and the child from the parent and it will work in either ways, because the propagation will not go backward.

Including Elastics::ModelSyncer

Sometimes you may have a model that doesn’t need to be indexed as a document, however part of its data is referred (and indexed) as part of another model. In that case you don’t need the full fledged Elastics::ModelIndexer which will add typical index related capabilities to your model (like index, type, store, remove, …). Indeed you need just to sync some other referring model(s). For example:

class NotIndexedModel
  belongs_to :parent
  include Elastics::ModelSyncer
  # parts of the data of this model are referred in :parent and :other_model
  elastics.sync :parent, :other_model

  def other_model
    # should return the record that needs to be synced
  end

end

In this example, each time a NotIndexedModel record changes, the :parent and the :other_model records will be synced. Notice that a Elastics::ModelSyncer.sync cannot sync self: indeed you included that module instead of Elastics::ModelIndexer exactly because you don’t need to sync self. :-)

Class Methods

elastics.sync(*synced)

With this method you actually define the callback needed to keep the index in sync when the record change, and set the elastics.synced array.

It accepts self, symbols and strings. For example:

elastics.sync self, :review, 'blog'
  • self will sync the record itself (it is required only for Elastics::ModelIndexer models, it's illegal for Elastics::ModelSyncer models and already included for Elastics::ActiveModel models)
  • :review is a symbol which identifies a method of the record, which is supposed to return another (relating) record. It is usually a belongs_to association symbol name, but it could be any method that you defined
  • 'blog' is a string which is supposed to be a parent name, as defined in a parent-child map (see elasticsearch Parent/Child Relationship)

When a record of this model changes, it is synced with its related elasticsearch-document, then the record returned by the record.review (must be a elastics model) is synced as well, and finally the parent record (defined in the parent/child relationship) is synced IF its type is blog.

elastics.synced

Attribute accessor for the Array of items to sync. You may need to set this Array only in the very special case that you want to sync the record manually. In that case you should not use the elastics.sync that does it automatically. (see also record.elastics.sync below). If you use Model.elastics.sync you can ignore this.

elastics.refresh_index

It refreshes the index by using Elastics.refresh_index API method. For automatic refresh you can also use Elastics::RefreshCallback (see Elastics::RefreshCallback).

Instance Methods

elastics.sync

It syncs the list of synced models, as set in the elastics.synced array. This method is automatically called when the record changes, so you probably don't need to use it explicitly. If you need to sync manually, then you should not use Model.elastics.sync(*synced) which will define the callbacks. Instead you should use Model.elastics.synced = [self, :other, ...] that causes the same behaviour, without setting the callbacks.

elastics.refresh_index

It refreshes the index by using Elastics.refresh_index API method. For automatic refresh you can also use Elastics::RefreshCallback (see Elastics::RefreshCallback).