Elasticsearch::DSL
The elasticsearch-dsl
library provides a Ruby API for
the Elasticsearch Query DSL.
The library is compatible with Ruby 1.9 or higher and Elasticsearch 1.0 and higher.
Installation
Install the package from Rubygems:
gem install elasticsearch-dsl
To use an unreleased version, either add it to your Gemfile
for Bundler:
gem 'elasticsearch-dsl', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
or install it from a source code checkout:
git clone https://github.com/elasticsearch/elasticsearch-ruby.git
cd elasticsearch-ruby/elasticsearch-dsl
bundle install
rake install
Usage
The library is designed as a group of standalone Ruby modules, classes and DSL methods, which provide an idiomatic way to build complex search definitions.
Let's have a simple example using the declarative variant:
require 'elasticsearch/dsl'
include Elasticsearch::DSL
definition = search do
query do
match title: 'test'
end
end
definition.to_hash
# => { query: { match: { title: "test"} } }
require 'elasticsearch'
client = Elasticsearch::Client.new trace: true
client.search body: definition
# curl -X GET 'http://localhost:9200/test/_search?pretty' -d '{
# "query":{
# "match":{
# "title":"test"
# }
# }
# }'
# ...
# => {"took"=>10, "hits"=> {"total"=>42, "hits"=> [...] } }
Let's build the same definition in a more imperative fashion:
require 'elasticsearch/dsl'
include Elasticsearch::DSL
definition = Search::Search.new
definition.query = Search::Queries::Match.new title: 'test'
definition.to_hash
# => { query: { match: { title: "test"} } }
The library doesn't depend on an Elasticsearch client -- its sole purpose is to facilitate building search definitions in Ruby. This makes it possible to use it with any Elasticsearch client:
require 'elasticsearch/dsl'
include Elasticsearch::DSL
definition = search { query { match title: 'test' } }
require 'json'
require 'faraday'
client = Faraday.new(url: 'http://localhost:9200')
response = JSON.parse(
client.post(
'/_search',
JSON.dump(definition.to_hash),
{ 'Accept' => 'application/json', 'Content-Type' => 'application/json' }
).body
)
# => {"took"=>10, "hits"=> {"total"=>42, "hits"=> [...] } }
Features Overview
The library allows to programatically build complex search definitions for Elasticsearch in Ruby, which are translated to Hashes, and ultimately, JSON, the language of Elasticsearch.
All Elasticsearch DSL features are supported, namely:
- Queries
- Filters
- Aggregations
- Suggestions
- Sorting
- Pagination
- Options (source filtering, highlighting, etc)
An example of a complex search definition would look like this:
require 'awesome_print'
require 'elasticsearch'
require 'elasticsearch/dsl'
include Elasticsearch::DSL
client = Elasticsearch::Client.new transport_options: { request: { timeout: 3600, open_timeout: 3600 } }
# Restore an index from a snapshot
#
client.indices.delete index: 'bicycles.stackexchange.com', ignore: 404
puts "Recovering the 'bicycles.stackexchange.com' index...".gray
client.snapshot.create_repository repository: 'data.elasticsearch.org', body: { type: 'url', settings: { url: 'https://s3.amazonaws.com/data.elasticsearch.org/bicycles.stackexchange.com/' } }
client.snapshot.restore repository: 'data.elasticsearch.org', snapshot: 'bicycles.stackexchange.com', body: { indices: 'bicycles.stackexchange.com' }
until client.cluster.health(level: 'indices')['indices']['bicycles.stackexchange.com']['status'] == 'green'
r = client.indices.status(index: 'bicycles.stackexchange.com', human: true, recovery: true)['indices']['bicycles.stackexchange.com']['shards']['0'][0]
print "\r#{r['index']['size']} of #{r['gateway_recovery']['index']['expected_recovered_size']}".ljust(52).gray
sleep 1
end
# The search definition
#
definition = search {
query do
# Use a `function_score` query to modify the default score
#
function_score do
query do
filtered do
# Use a `multi_match` query for the fulltext part of the search
#
query do
multi_match do
query 'fixed fixie'
operator 'or'
fields %w[ title^10 body ]
end
end
# Use a `range` filter on the `creation_date` field
#
filter do
range :creation_date do
gte '2013-01-01'
end
end
end
end
# Multiply the default `_score` by a (slightly normalized) document rating
#
functions << { script_score: { script: '_score * log10( doc["rating"].value )' } }
end
end
# Calculate the most frequently used tags
#
aggregation :tags do
terms do
field 'tags'
end
end
# Calculate the posting frequency
#
aggregation :frequency do
date_histogram do
field 'creation_date'
interval 'month'
format 'yyyy-MM'
end
end
# Calculate the statistical information about the number of comments
#
aggregation :comment_count_stats do
stats field: 'comment_count'
end
# Highlight the `title` and `body` fields
#
highlight fields: {
title: { fragment_size: 50 },
body: { fragment_size: 50 }
}
# Return only a selection of the fields
#
source ['title', 'tags', 'creation_date', 'rating', 'user.location', 'user.display_name']
}
puts "Search definition #{'-'*63}\n".gray
ap definition.to_hash
# Execute the search request
#
response = client.search index: 'bicycles.stackexchange.com', type: ['question','answer'], body: definition
puts "\nSearch results #{'-'*66}\n".gray
ap response
Please see the extensive RDoc examples in the source code and the integration tests.
Development
To work on the code, clone the repository and install the dependencies:
git clone https://github.com/elasticsearch/elasticsearch-ruby.git
cd elasticsearch-ruby/elasticsearch-dsl/
bundle install
Use the Rake tasks to run the test suites:
bundle exec rake test:unit
bundle exec rake test:integration
To launch a separate Elasticsearch server for integration tests, see instructions in the main README.
License
This software is licensed under the Apache 2 license, quoted below.
Copyright (c) 2015 Elasticsearch <http://www.elasticsearch.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.