3. What is ElasticSearch?
ElasticSearch is a scalable, distributed, cloud-
ready, highly-available, full-text search engine and
database with powerfull aggregation features,
communicating by JSON over RESTful HTTP,
based on Lucene, written in Java.
4. What's so great about
ElasticSearch?
1.No configuration to get started.
2.RESTful - we all know it and love it
3.Schemaless JSON datasource
4.MultiTenancy - multiple indexes and the ability
to search across them
5.Settings - each index can have it's own
settings
6.Distributed by nature
7.Gateway concept for easy restore and backup
6. What does it have over
Solr?
A detailed comparison
http://blog.sematext.com/2012/08/23/solr-vs-
elasticsearch-part-1-overview/
My Opinion:
1.Easier to setup
2.Easy to understand
3.REST + JSON
4.Built for Cloud Computing
5.Foundation of Solr with a new approach
6.SUPER fast with realtime search
7. Where the railscasts left off...
class Post < ActiveRecord::Base
attr_accessible :title, :body, :user_id
belongs_to :user
include Tire::Model::Search
include Tire::Model::Callbacks
mapping do
indexes :id, type: 'integer', index: :not_analyzed
indexes :title
indexes :body
indexes :user_full_name, boost: 10
indexes :user_id, type: 'integer', index: :not_analyzed
indexes :created_at, type: 'date', index: :not_analyzed
end
8. Where the railscasts left off...
def self.search(params)
tire.search(page: params[:page], per_page: 3) do
query do
boolean do
must { string params[:query], default_operator: "AND" } if params[:query].present?
must { range :created_at, lte: Time.zone.now }
must { term :user_id, params[:user_id] } if params[:user_id].present?
end
end
sort { by :created_at, "desc" } if params[:query].blank?
facet "users" do
terms :user_id
end
end
end
def to_indexed_json
to_json(methods: [:user_full_name])
end
def user_full_name
user.full_name
end
end
9. Where the railscasts left off...
<div id="posts">
<% @posts.each do |post| %>
<h2><%= link_to post.title, post %></h2>
<div class="info">
by <%= post.user_full_name %>
on <%= post.created_at.to_time.strftime('%b %d, %Y') %>
</div>
<div class="body">
<%= post.body %>
</div>
<% end %>
</div>
10. Where the railscasts left off...
class Post < ActiveRecord::Base
attr_accessible :title, :body, :user_id
belongs_to :user
include Tire::Model::Search
include Tire::Model::Callbacks
mapping do
indexes :id, type: 'integer', index: :not_analyzed
indexes :title
indexes :body
indexes :user_full_name, boost: 10
indexes :user_id, type: 'integer', index: :not_analyzed
indexes :created_at, type: 'date', index: :not_analyzed
end
def self.search(params)
tire.search(page: params[:page], per_page: 3) do
query do
boolean do
must { string params[:query], default_operator: "AND" } if
params[:query].present?
must { range :created_at, lte: Time.zone.now }
must { term :user_id, params[:user_id] } if params[:user_id].present?
end
end
11. Cleaning House
mapping do
indexes :id, type: 'integer', index: :not_analyzed
indexes :title
indexes :body
indexes :user do
indexes :full_name, boost: 10
end
indexes :user_id, type: 'integer', index: :not_analyzed
indexes :created_at, type: 'date', index: :not_analyzed
end
def to_indexed_json
to_json(include: {user: { methods: [:full_name] } })
end
<div id="posts">
<% @posts.each do |post| %>
<h2><%= link_to post.title, post %></h2>
<div class="info">
by <%= post.user.full_name %>
on <%= post.created_at.to_time.strftime('%b %d, %Y') %>
</div>
<div class="body">
<%= post.body %>
</div>
<% end %>
</div>
12. Stay In Sync
class User < ActiveRecord::Base
attr_accessible :first_name, :last_name, :bio
has_many :posts
after_save { self.posts.each{ |p| p.tire.update_index } }
def full_name
"#{self.first_name} #{self.last_name}"
end
end
class Post < ActiveRecord::Base
attr_accessible :title, :body, :user_id
belongs_to :user
include Tire::Model::Search
include Tire::Model::Callbacks
mapping do
indexes :id, type: 'integer', index: :not_analyzed
indexes :title
indexes :body
indexes :user do
indexes :full_name, boost: 10
end
indexes :user_id, type: 'integer', index: :not_analyzed
indexes :created_at, type: 'date', index: :not_analyzed
end
13. Analyzers
Elastic Search indexes document with tokens extracted
from properties. Prefix search is a specific need and is
handled with edge ngram, a variant of ngram. Ngram is
a group a contiguous letters extracted from a word.
Edge ngram is a ngram built from the start or the end
of a word.
A token filter of type asciifolding that converts
alphabetic, numeric, and symbolic Unicode characters
which are not in the first 127 ASCII characters (the
“Basic Latin” Unicode block) into their ASCII
equivalents, if one exists.
14. Indexing Partial Words
class Post < ActiveRecord::Base
attr_accessible :title, :body, :user_id
belongs_to :user
include Tire::Model::Search
include Tire::Model::Callbacks
settings analysis: {
filter: {
front_edge: {
type: "edgeNGram",
side: "front",
max_gram: 8,
min_gram: 4
}
},
analyzer: {
partial_match: {
tokenizer: "whitespace",
filter: %w{asciifolding lowercase front_edge}
},
whole_sort: {
tokenizer: 'keyword',
filter: %w{asciifolding lowercase}
}
}
} do
...............
16. Indexing Partial Words
...........
def self.search(params)
tire.search(page: params[:page], per_page: 3) do
query do
boolean do
must { string "body.start:#{params[:query]} OR body.kw:#{params[:query]}
OR #{params[:query]}", default_operator: "AND" } if params[:query].present?
must { range :created_at, lte: Time.zone.now }
must { term :user_id, params[:user_id] } if params[:user_id].present?
end
end
if params[:query].blank?
sort { by :created_at, "desc" }
else
sort {by 'body.sort', 'asc' }
end
facet "users" do
terms :user_id
end
end
end
def to_indexed_json
to_json(include: {user: { methods: [:full_name] } })
end
end