Skip to content
A rich Ruby API and DSL for the ElasticSearch search engine/database
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



Slingshot aims to provide a rich Ruby API and DSL for the ElasticSearch search engine/database.

ElasticSearch is a scalable, distributed, highly-available, RESTful database communicating by JSON over HTTP, based on Lucene, written in Java. It manages to very simple and very powerful at the same time. You should seriously consider it to power search in your Ruby applications: it will deliver all the features you want — and many more you may have not imagined yet (native geo search? histogram facets?)

Slingshot currently allow basic operation with the index and searching. See chapters below.


First, you need a running ElasticSearch server. Thankfully, it's easy. Let's define easy:

$ curl -L -o elasticsearch-0.14.4.tar.gz
$ tar -zxvf elasticsearch-0.14.4.tar.gz
$ ./elasticsearch-0.14.4/bin/elasticsearch -f

OK, easy. Now, install the gem via Rubygems:

$ gem install slingshot

or from source:

$ git clone git://
$ rake install


Currently, you can use Slingshot via the DSL (eg. by extending your class with it). Plans for full ActiveModel integration (and other convenience layers) are in progress.

To kick the tiers, require the gem in an IRB session or a Ruby script (note that you can run the full example from examples/dsl.rb):

require 'rubygems'
require 'slingshot'

First, let's create an index named articles and store/index some documents:

Slingshot.index 'articles' do

  store :title => 'One',   :tags => ['ruby']
  store :title => 'Two',   :tags => ['ruby', 'python']
  store :title => 'Three', :tags => ['java']
  store :title => 'Four',  :tags => ['ruby', 'php']


Now, let's query the database:

We are searching for articles tagged ruby, sorted by title in descending order, and also retrieving some facets from the database:

s = 'articles' do
  query do
    terms :tags, ['ruby']

  sort do
    title 'desc'

  facet 'global-tags' do
    terms :tags, :global => true

  facet 'current-tags' do
    terms :tags

Let's display the results:

s.results.each do |document|
  puts "* #{ document['_source']['title'] }"

# * Two
# * One
# * Four

Let's display the facets (distribution of tags across the whole database):

s.results.facets['global-tags']['terms'].each do |f|
  puts "#{f['term'].ljust(10)} #{f['count']}"

# ruby       3
# python     1
# php        1
# java       1

We can display the full query JSON:

puts s.to_json
# {"facets":{"current-tags":{"terms":{"field":"tags"}},"global-tags":{"global":true,"terms":{"field":"tags"}}},"sort":[{"title":"desc"}],"query":{"terms":{"tags":["ruby"]}}}

See, a Ruby DSL for this thing is kinda handy? We can query ElasticSearch manually with curl, simply:

puts s.to_curl
# curl -X POST "http://localhost:9200/articles/_search?pretty=true" -d '{"facets":{"current-tags":{"terms":{"field":"tags"}},"global-tags":{"global":true,"terms":{"field":"tags"}}},"sort":[{"title":"desc"}],"query":{"terms":{"tags":["ruby"]}}}'


Currently, Slingshot supports only a limited subset of vast ElasticSearch Search API and it's Query DSL:

  • Creating, deleting and refreshing the index
  • Storing a document in the index
  • Querying the index with the query_string, term and terms types of queries
  • Sorting the results by fields
  • Retrieving a terms type of facets -- other types are high priority
  • Returning just specific fields from documents
  • Paging with from and size query options

See the examples/dsl.rb.

Todo & Plans

In order of importance:

  • Basic wrapper class for hits in results, so we could write results.first.document.title instead of using the raw Hash
  • Getting document by ID
  • Seamless ActiveModel compatibility for easy usage in Rails applications (this also means nearly full ActiveRecord compatibility)
  • Allowing to set custom non-ActiveModel wrapper class (your own)
  • Seamless will_paginate compatibility for easy pagination
  • Histogram facets
  • Seamless support for auto-updating river index for CouchDB _changes feed
  • Mapping management
  • Infrastructure for query filters
  • Range filters and queries
  • Geo Filters for queries
  • Statistical facets
  • Geo Distance facets
  • Index aliases management
  • Analyze API support
  • Highligting support
  • Bulk API
  • Embedded webserver to display cluster statistics and allow easy searches


You can send feedback via e-mail or via Github Issues.

Karel Minarik

Something went wrong with that request. Please try again.