A damn simple mixin for integrating ActiveModel with ElasticSearch.
MIT License
A damn simple mixin for integrating ActiveModel with ElasticSearch.
ElasticMapper is built on top of the Stretcher client.
I'm a big fan of the Stretcher ElasticSearch client. It exposes an API that's: straightforward, elegant, and well documented. I tend to choose stretcher when pulling search into Rails projects.
A few projects in, I noticed that I was rewriting a lot of the same code for:
From this grew ElasticMapper; Simply include the ElasticMapper mixin in your ActiveModels, it provides helpers for: generating mappings, indexing documents, and performing search.
Mappings indicate to ElasticSearch how the fields of a document should be indexed:
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping.html
ElasticMapper provides a mapping
method, for describing these mappings.
def Article < ActiveHash::Base
include ElasticMapper
# Note we might sometimes want to index the same field in a few
# different ways, ElasticMapper creates a unique name automatically
# if fields collide :title, :title_1, ...
mapping :title, :doi, { type => :string, index => :not_analyzed }
mapping :title, :abstract, type => :string
mapping :publication_date, type => :date
end
When you create or modify mappings on an ElasticMapper model, you should run:
Article.put_mapping
When you create or update a document using the ElasticMapper mixin, simply call index
.
article = Article.create(title: "Hello World", doi: "doi://12354.com")
article.index
Or, even easier, use the ActiveRecord :after_save
hook:
class Article < ActiveRecord::Base
include ElasticMapper
validates_uniqueness_of :doi
validates_presence_of :doi, :title
after_save :index
mapping :title, :doi, :index => :not_analyzed
mapping :title, :abstract
mapping :publication_date, :type => :date
end
To remove a document from ElasticSearch, use the delete_from_index
method.
class Article < ActiveRecord::Base
include ElasticMapper
after_destroy :delete_from_index
end
ElasticMapper adds the search
method to your ActiveModel classes. Results will be returned as instances of your ActiveModel class.
String Queries
You can provide a string query to your model, and it will be parsed using the ElasticSearch query DSL:
articles = Article.search('hello AND world')
Hash Queries
You can also provide a hash object, for advanced searches.
articles = Article.search({ "query_string" => { "query" => 'alpha' } })
Pagination
:size
how many search results should be returned?:from
what offset should we start returning results from?results = SearchModel.search('* OR alpha', size: 10, from: 10)
Suppose you have two mappings in ElasticSearch, for instance an article
and
a user
. There are times when you might want to search across both models
at the same time.
This can be facilitated with ElasticMapper's MultiSearch
class:
multi = ElasticMapper::MultiSearch.new({
index_models: SearchModel,
index_models_two: SearchModelTwo
})
results = multi.search('* OR alpha', size: 1)
MultiSearch
instance, search works the same as it does when using the ActiveModel mixin.Let me know what you think!
Add this line to your application's Gemfile:
gem 'elastic_mapper'
And then execute:
$ bundle
Or install it yourself as:
$ gem install elastic_mapper
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)