ActiveModel Integration
When you want a familiar way to populate and search your index without even need to know elasticsearch or when the data you have to index is external to your app (for example if you crawl a site and want to build a searchable index out of it), you can just manage the index like you were managing any active model, still keeping the searching capability of Elastics::Scopes
and/or Elastics::Templates
.
Notice: The result returned by querying elasticsearch with a
Elastics::ActiveModel
model, return always regular instance of your class, not the original elasticsearch result structure. However you can always get the raw result by just callingraw_result
on the array collection or any model instance.
The key concept is that you create a model per (elasticsearch) type
, similarly to what you would do with a DB: a model per table/collection. You do so by including Elastics::ActiveModel
which also includes Elastics::ModelIndexer
, so you will have all the elastics.*
methods available both at the class level and at the instance level (see Elastics::ModelIndexer).
Then you declare the model attributes names, and optionally their default and typecasting. You can eventually set also the elasticsearch mapping properties for each attribute that may need it, and you can use it as any other model. For example:
class Product
include Elastics::ActiveModel
# if we omit the next line, the elasticsearch type would have been 'product' by default
elastics.type = 'goods'
attribute :name
# optional elasticsearch properties mapping
attribute :price, :properties => {'type' => 'float'}, :default => 0
# :analyzed => false is a shortcut to :properties => { 'type' => 'string', 'index' => 'not_analyzed' }
attribute :color, :analyzed => false
# this adds a :created_at and :updated_at attributes
attribute_timestamps
# standard validation
validate :name, :presence => true
# standard callback
before_create { self.name = name.titleize }
# named scope
scope :red, term(:color => 'red')
end
# indexes the data in elasticsearch
product = Product.new :name => 'my_name',
:color => 'blue',
:price => 9.99
product.save if product.valid?
red_products = Product.red.all
product = Product.find('a09rf')
total = Product.count
Capabilities
By including Elastics::ActiveModel
your model gets the following capabilities:
Validation
Validation is provided verbatim by ActiveModel
(see activemodel) so you an use all its standard validation methods.
Callbacks
Elastics::ActiveModel
provides the create
, update
, save
and destroy
callbacks backed by ActiveModel
, so you can use them as usual with the before_*
and after_*
prefixes.
Attributes
By including Elastics::ActiveModel
you include also the ActiveAttr::Model
. It provides a lot of useful goodies, like attribute declarations with defaults and typecasting (see active_attr). Besides, elastics extends it with a few features (see Class Methods)
Versioning and optimistic lock updating
Elastics::ActiveModel
adds the versioning to your models (see elasticsearch Versioning, so your model has always a _version
attribute. Besides, it implements the lock updating throught the method lock_update
(see Safe Update).
Finders, Scopes and Templates
Elastics::ActiveModel
includes also the Elastics::Scopes
by default, so you have all the cool finders and chainable scopes ready to use in your model (see elastics-scopes)
Besides, if you need more power to easily write complex queries, you can include the Elastics::Templates
module and use it as usual (see Templating)
Methods
(see Elastics::ActiveModel, Elastics::ModelIndexer and Elastics::ModelSyncer)