SlideShare a Scribd company logo
Elasticsearch
And Ruby

Karel Minařík
http://karmi.cz


                  Elasticsearch and Ruby
{elasticsearch in a nutshell}


Built on top of Apache Lucene
Searching and analyzing big data
Scalability
REST API, JSON DSL



Great fit for dynamic languages and web-oriented workflows / architectures

http://www.elasticsearch.org                                   Elasticsearch and Ruby
{ }
      Elasticsearch and Ruby
{ }
  It all started in this gist… (< 200 LOC)




                  Elasticsearch and Ruby
{ }
      Elasticsearch and Ruby
Example


 class Results
   include Enumerable
   attr_reader :query, :curl, :time, :total, :results, :facets

  def initialize(search)
    response = JSON.parse( Slingshot.http.post("http://localhost:9200/#{search.indices}/_search", search.to_json) )
    @query   = search.to_json
    @curl    = %Q|curl -X POST "http://localhost:9200/#{search.indices}/_search?pretty" -d '#{@query}'|
    @time    = response['took']
    @total   = response['hits']['total']
    @results = response['hits']['hits']
    @facets = response['facets']
  end

   def each(&block)
     @results.each(&block)
   end
 end




                                                                     Elasticsearch plays nicely with Ruby…


                                                                                            Elasticsearch and Ruby
elasticsearch’s Query DSL
curl  -­‐X  POST  "http://localhost:9200/articles/_search?pretty=true"  -­‐d  '
{
    "query"  :  {
        "filtered"  :  {
            "filter"  :  {
                "range"  :  {
                    "date"  :  {
                        "from"  :  "2012-­‐01-­‐01",
                        "to"      :  "2012-­‐12-­‐31"
                    }
                }
            },
            "query"  :  {
                "bool"  :  {
                    "must"  :  {
                        "terms"  :  {
                            "tags"  :  [  "ruby",  "python"  ]
                        }
                    },
                    "must"  :  {
                        "match"  :  {
                            "title"  :  {
                                "query"  :  "conference",
                                "boost"  :  10.0
                            }
                        }
                    }
                }
            }
        }
    }
}
Example


 Tire.search('articles') do
   query do
     boolean do
       must { terms :tags, ['ruby', 'python'] }
       must { string 'published_on:[2011-01-01 TO 2011-01-02]' }
     end
   end
 end




                                                         Elasticsearch and Ruby
Example

 tags_query = lambda do |boolean|
   boolean.must { terms :tags, ['ruby', 'python'] }
 end

 published_on_query = lambda do |boolean|
   boolean.must   { string 'published_on:[2011-01-01 TO 2011-01-02]' }
 end

 Tire.search('articles') do
   query { boolean &tags_query }
 end

 Tire.search('articles') do
   query do
     boolean &tags_query
     boolean &published_on_query
   end
 end



                                                         Elasticsearch and Ruby
Example

 search = Tire.search 'articles' do
   query do
     string 'title:T*'
   end
   filter :terms, tags: ['ruby']
   facet 'tags', terms: tags
   sort   { by :title, 'desc' }
 end




                        search = Tire::Search::Search.new('articles')
                        search.query { string('title:T*') }
                        search.filter :terms, :tags => ['ruby']
                        search.facet('tags') { terms :tags }
                        search.sort   { by :title, 'desc' }




                                                         Elasticsearch and Ruby
TEH PROBLEM




     Designing the Tire library as domain-specific language, from the higher level, and
     consequently doing a lot of mistakes in the lower levels.

     ‣ Class level settings (Tire.configure); cannot connect to two elasticsearch clusters in one codebase
     ‣ Inconsistent access (methods vs Hashes)
     ‣ Not enough abstraction and separation of concerns

                                                                                           Elasticsearch and Ruby
”Blocks with arguments”
      (alternative DSL syntax)




     Tire.search do
       query do
         text :name, params[:q]
       end
     end


Tire.search do   |search|
  search.query   do |query|
    query.text   :name, params[:q]
  end
end              Elasticsearch and Ruby
The Git(Hub) (r)evolution
‣ Lots of contributions... but less feedback
‣ Many contributions focus on specific use case
‣ Many contributions don’t take the bigger picture and codebase conventions into account

‣ Almost every patch needs to be processed, polished, amended
‣ Maintainer: lots of curation, less development — even on this small scale (2K LOC, 7K LOT)

‣ Contributors very eager to code, but a bit afraid to talk
Tire’s Ruby on Rails integration

$  rails  new  myapp  
      -­‐m  "https://raw.github.com/karmi/tire/master/examples/rails-­‐application-­‐template.rb"



‣ Generate a fully working Rails application with a single command
‣ Downloads elasticsearch if not running, creates the application, commits
  every step, seeds the example data, launches the application on a free port, …
‣ Tire::Results::Item fully compatible with Rails view / URL helpers

‣ Any ActiveModel compatible OxM supported
‣ Rake task for importing data (using pagination libraries)




                                                                              Elasticsearch and Ruby
Rails integration baked in
‣ No proper separation of concerns / layers
‣ People expect everything to be as easy as that
‣ Tire::Results::Item baked in, not opt-in, masquerades as models

‣ People consider ActiveRecord the only OxM in the world
                                                                    Elasticsearch and Ruby
…


Persistence extension


Rails extensions


ActiveRecord extensions


ActiveModel integration


The Ruby DSL


Base library (HTTP, JSON, API)
https://rubygems.org
https://github.com/rubygems/rubygems.org/pull/455
“Search”
class Rubygem < ActiveRecord::Base
  # ...

  def self.search(query)
    conditions = <<-SQL
      versions.indexed and
        (upper(name) like upper(:query) or
         upper(translate(name, '#{SPECIAL_CHARACTERS}', '#{' ' *
SPECIAL_CHARACTERS.length}')) like upper(:query))
    SQL

    where(conditions, {:query => "%#{query.strip}%"}).
      includes(:versions).
      by_downloads
  end
end




https://github.com/rubygems/rubygems.org/blob/master/app/models/rubygem.rb   Elasticsearch and Ruby
1



2


3




4
5

6




    Adding search to an existing application
https://github.com/karmi/rubygems.org/compare/search-steps
“Hello Cloud” with Chef Server


http://git.io/chef-hello-cloud
‣   Deploy Rubygems.org on EC2 (or locally with Vagrant) from a “zero state”
‣   1 load balancer (HAproxy), 3 application servers (Thin+Nginx)
‣   1 database node (PostgreSQL, Redis)
‣   2 elasticsearch nodes
‣   Install Ruby 1.9.3 via RVM
‣   Clone the application from GitHub repository
‣   init.d   scripts and full configuration for every component
‣   Restore data from backup (database dump) and import into search index
‣   Monitor every part of the stack


                                                                  Elasticsearch and Ruby
Thanks!
  d

More Related Content

PDF
Elasticsearch in 15 Minutes
PDF
Elasticsearch (Rubyshift 2013)
PDF
Simple search with elastic search
PDF
Elasticsearch in 15 minutes
PDF
elasticsearch - advanced features in practice
PPTX
Elastic search Walkthrough
ODP
Cool bonsai cool - an introduction to ElasticSearch
PDF
Side by Side with Elasticsearch and Solr
Elasticsearch in 15 Minutes
Elasticsearch (Rubyshift 2013)
Simple search with elastic search
Elasticsearch in 15 minutes
elasticsearch - advanced features in practice
Elastic search Walkthrough
Cool bonsai cool - an introduction to ElasticSearch
Side by Side with Elasticsearch and Solr

What's hot (20)

PDF
Introduction to Elasticsearch
ODP
Terms of endearment - the ElasticSearch Query DSL explained
PDF
ElasticSearch - index server used as a document database
PDF
Distributed percolator in elasticsearch
PPTX
Solr vs. Elasticsearch - Case by Case
PDF
Dcm#8 elastic search
PDF
Introduction to solr
PDF
Data Exploration with Elasticsearch
PDF
ElasticSearch in action
PDF
Debugging and Testing ES Systems
PDF
Elasticsearch first-steps
PDF
Elasticsearch: You know, for search! and more!
PPTX
ElasticSearch - DevNexus Atlanta - 2014
PDF
Introduction to Elasticsearch
PDF
Introduction to Elasticsearch
PDF
Redis: REmote DIctionary Server
PDF
Use Cases for Elastic Search Percolator
PDF
Json the-x-in-ajax1588
PPTX
ElasticSearch AJUG 2013
PDF
Automatically generating-json-from-java-objects-java-objects268
Introduction to Elasticsearch
Terms of endearment - the ElasticSearch Query DSL explained
ElasticSearch - index server used as a document database
Distributed percolator in elasticsearch
Solr vs. Elasticsearch - Case by Case
Dcm#8 elastic search
Introduction to solr
Data Exploration with Elasticsearch
ElasticSearch in action
Debugging and Testing ES Systems
Elasticsearch first-steps
Elasticsearch: You know, for search! and more!
ElasticSearch - DevNexus Atlanta - 2014
Introduction to Elasticsearch
Introduction to Elasticsearch
Redis: REmote DIctionary Server
Use Cases for Elastic Search Percolator
Json the-x-in-ajax1588
ElasticSearch AJUG 2013
Automatically generating-json-from-java-objects-java-objects268
Ad

Similar to Elasticsearch And Ruby [RuPy2012] (20)

PPTX
Introduction to ElasticSearch
PDF
Elasticsearch Basics
PDF
Mastering ElasticSearch with Ruby and Tire
PDF
Workshop: Learning Elasticsearch
KEY
Elastic tire demo
PDF
All about elasticsearch language clients
PDF
Finding the right stuff, an intro to Elasticsearch (at Rug::B)
PDF
Finding the right stuff, an intro to Elasticsearch with Ruby/Rails
PDF
Using elasticsearch with rails
PPT
How ElasticSearch lives in my DevOps life
ODP
Elastic Search
KEY
Elasticsearch & "PeopleSearch"
PDF
Kyiv.py #16 october 2015
PDF
APIs for mobile
PDF
How to Begin to Develop Ruby Core
PDF
Rails and the Apache SOLR Search Engine
PPTX
Elastic pivorak
KEY
Rails Presentation (Anton Dmitriyev)
PDF
Solving text search problems with Ruby on Rails
PPTX
Elasticsearch, Logstash, Kibana. Cool search, analytics, data mining and more...
Introduction to ElasticSearch
Elasticsearch Basics
Mastering ElasticSearch with Ruby and Tire
Workshop: Learning Elasticsearch
Elastic tire demo
All about elasticsearch language clients
Finding the right stuff, an intro to Elasticsearch (at Rug::B)
Finding the right stuff, an intro to Elasticsearch with Ruby/Rails
Using elasticsearch with rails
How ElasticSearch lives in my DevOps life
Elastic Search
Elasticsearch & "PeopleSearch"
Kyiv.py #16 october 2015
APIs for mobile
How to Begin to Develop Ruby Core
Rails and the Apache SOLR Search Engine
Elastic pivorak
Rails Presentation (Anton Dmitriyev)
Solving text search problems with Ruby on Rails
Elasticsearch, Logstash, Kibana. Cool search, analytics, data mining and more...
Ad

More from Karel Minarik (20)

PDF
Vizualizace dat a D3.js [EUROPEN 2014]
PDF
Realtime Analytics With Elasticsearch [New Media Inspiration 2013]
PDF
Shell's Kitchen: Infrastructure As Code (Webexpo 2012)
PDF
Elastic Search: Beyond Ordinary Fulltext Search (Webexpo 2011 Prague)
PDF
Your Data, Your Search, ElasticSearch (EURUKO 2011)
PDF
Redis — The AK-47 of Post-relational Databases
PDF
CouchDB – A Database for the Web
PDF
Spoiling The Youth With Ruby (Euruko 2010)
PDF
Verzovani kodu s Gitem (Karel Minarik)
PDF
Představení Ruby on Rails [Junior Internet]
PDF
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
PDF
Úvod do Ruby on Rails
PDF
Úvod do programování 7
PDF
Úvod do programování 6
PDF
Úvod do programování 5
PDF
Úvod do programování 4
PDF
Úvod do programování 3 (to be continued)
PDF
Historie programovacích jazyků
PDF
Úvod do programování aneb Do nitra stroje
PDF
Interaktivita, originalita a návrhové vzory
Vizualizace dat a D3.js [EUROPEN 2014]
Realtime Analytics With Elasticsearch [New Media Inspiration 2013]
Shell's Kitchen: Infrastructure As Code (Webexpo 2012)
Elastic Search: Beyond Ordinary Fulltext Search (Webexpo 2011 Prague)
Your Data, Your Search, ElasticSearch (EURUKO 2011)
Redis — The AK-47 of Post-relational Databases
CouchDB – A Database for the Web
Spoiling The Youth With Ruby (Euruko 2010)
Verzovani kodu s Gitem (Karel Minarik)
Představení Ruby on Rails [Junior Internet]
Efektivni vyvoj webovych aplikaci v Ruby on Rails (Webexpo)
Úvod do Ruby on Rails
Úvod do programování 7
Úvod do programování 6
Úvod do programování 5
Úvod do programování 4
Úvod do programování 3 (to be continued)
Historie programovacích jazyků
Úvod do programování aneb Do nitra stroje
Interaktivita, originalita a návrhové vzory

Recently uploaded (20)

PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
A Presentation on Artificial Intelligence
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Electronic commerce courselecture one. Pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
sap open course for s4hana steps from ECC to s4
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Empathic Computing: Creating Shared Understanding
Unlocking AI with Model Context Protocol (MCP)
Reach Out and Touch Someone: Haptics and Empathic Computing
A Presentation on Artificial Intelligence
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Assigned Numbers - 2025 - Bluetooth® Document
Electronic commerce courselecture one. Pdf
Machine learning based COVID-19 study performance prediction
Per capita expenditure prediction using model stacking based on satellite ima...
NewMind AI Weekly Chronicles - August'25-Week II
Mobile App Security Testing_ A Comprehensive Guide.pdf
Network Security Unit 5.pdf for BCA BBA.
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
The Rise and Fall of 3GPP – Time for a Sabbatical?
Programs and apps: productivity, graphics, security and other tools
sap open course for s4hana steps from ECC to s4
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
MYSQL Presentation for SQL database connectivity
Spectral efficient network and resource selection model in 5G networks
Empathic Computing: Creating Shared Understanding

Elasticsearch And Ruby [RuPy2012]

  • 2. http://karmi.cz Elasticsearch and Ruby
  • 3. {elasticsearch in a nutshell} Built on top of Apache Lucene Searching and analyzing big data Scalability REST API, JSON DSL Great fit for dynamic languages and web-oriented workflows / architectures http://www.elasticsearch.org Elasticsearch and Ruby
  • 4. { } Elasticsearch and Ruby
  • 5. { } It all started in this gist… (< 200 LOC) Elasticsearch and Ruby
  • 6. { } Elasticsearch and Ruby
  • 7. Example class Results include Enumerable attr_reader :query, :curl, :time, :total, :results, :facets def initialize(search) response = JSON.parse( Slingshot.http.post("http://localhost:9200/#{search.indices}/_search", search.to_json) ) @query = search.to_json @curl = %Q|curl -X POST "http://localhost:9200/#{search.indices}/_search?pretty" -d '#{@query}'| @time = response['took'] @total = response['hits']['total'] @results = response['hits']['hits'] @facets = response['facets'] end def each(&block) @results.each(&block) end end Elasticsearch plays nicely with Ruby… Elasticsearch and Ruby
  • 8. elasticsearch’s Query DSL curl  -­‐X  POST  "http://localhost:9200/articles/_search?pretty=true"  -­‐d  ' {    "query"  :  {        "filtered"  :  {            "filter"  :  {                "range"  :  {                    "date"  :  {                        "from"  :  "2012-­‐01-­‐01",                        "to"      :  "2012-­‐12-­‐31"                    }                }            },            "query"  :  {                "bool"  :  {                    "must"  :  {                        "terms"  :  {                            "tags"  :  [  "ruby",  "python"  ]                        }                    },                    "must"  :  {                        "match"  :  {                            "title"  :  {                                "query"  :  "conference",                                "boost"  :  10.0                            }                        }                    }                }            }        }    } }
  • 9. Example Tire.search('articles') do query do boolean do must { terms :tags, ['ruby', 'python'] } must { string 'published_on:[2011-01-01 TO 2011-01-02]' } end end end Elasticsearch and Ruby
  • 10. Example tags_query = lambda do |boolean| boolean.must { terms :tags, ['ruby', 'python'] } end published_on_query = lambda do |boolean| boolean.must { string 'published_on:[2011-01-01 TO 2011-01-02]' } end Tire.search('articles') do query { boolean &tags_query } end Tire.search('articles') do query do boolean &tags_query boolean &published_on_query end end Elasticsearch and Ruby
  • 11. Example search = Tire.search 'articles' do query do string 'title:T*' end filter :terms, tags: ['ruby'] facet 'tags', terms: tags sort { by :title, 'desc' } end search = Tire::Search::Search.new('articles') search.query { string('title:T*') } search.filter :terms, :tags => ['ruby'] search.facet('tags') { terms :tags } search.sort { by :title, 'desc' } Elasticsearch and Ruby
  • 12. TEH PROBLEM Designing the Tire library as domain-specific language, from the higher level, and consequently doing a lot of mistakes in the lower levels. ‣ Class level settings (Tire.configure); cannot connect to two elasticsearch clusters in one codebase ‣ Inconsistent access (methods vs Hashes) ‣ Not enough abstraction and separation of concerns Elasticsearch and Ruby
  • 13. ”Blocks with arguments” (alternative DSL syntax) Tire.search do query do text :name, params[:q] end end Tire.search do |search| search.query do |query| query.text :name, params[:q] end end Elasticsearch and Ruby
  • 14. The Git(Hub) (r)evolution ‣ Lots of contributions... but less feedback ‣ Many contributions focus on specific use case ‣ Many contributions don’t take the bigger picture and codebase conventions into account ‣ Almost every patch needs to be processed, polished, amended ‣ Maintainer: lots of curation, less development — even on this small scale (2K LOC, 7K LOT) ‣ Contributors very eager to code, but a bit afraid to talk
  • 15. Tire’s Ruby on Rails integration $  rails  new  myapp        -­‐m  "https://raw.github.com/karmi/tire/master/examples/rails-­‐application-­‐template.rb" ‣ Generate a fully working Rails application with a single command ‣ Downloads elasticsearch if not running, creates the application, commits every step, seeds the example data, launches the application on a free port, … ‣ Tire::Results::Item fully compatible with Rails view / URL helpers ‣ Any ActiveModel compatible OxM supported ‣ Rake task for importing data (using pagination libraries) Elasticsearch and Ruby
  • 16. Rails integration baked in ‣ No proper separation of concerns / layers ‣ People expect everything to be as easy as that ‣ Tire::Results::Item baked in, not opt-in, masquerades as models ‣ People consider ActiveRecord the only OxM in the world Elasticsearch and Ruby
  • 17. … Persistence extension Rails extensions ActiveRecord extensions ActiveModel integration The Ruby DSL Base library (HTTP, JSON, API)
  • 19. “Search” class Rubygem < ActiveRecord::Base # ... def self.search(query) conditions = <<-SQL versions.indexed and (upper(name) like upper(:query) or upper(translate(name, '#{SPECIAL_CHARACTERS}', '#{' ' * SPECIAL_CHARACTERS.length}')) like upper(:query)) SQL where(conditions, {:query => "%#{query.strip}%"}). includes(:versions). by_downloads end end https://github.com/rubygems/rubygems.org/blob/master/app/models/rubygem.rb Elasticsearch and Ruby
  • 20. 1 2 3 4 5 6 Adding search to an existing application
  • 22. “Hello Cloud” with Chef Server http://git.io/chef-hello-cloud ‣ Deploy Rubygems.org on EC2 (or locally with Vagrant) from a “zero state” ‣ 1 load balancer (HAproxy), 3 application servers (Thin+Nginx) ‣ 1 database node (PostgreSQL, Redis) ‣ 2 elasticsearch nodes ‣ Install Ruby 1.9.3 via RVM ‣ Clone the application from GitHub repository ‣ init.d scripts and full configuration for every component ‣ Restore data from backup (database dump) and import into search index ‣ Monitor every part of the stack Elasticsearch and Ruby