This guide walks you from installation through creating and searching your first index.
Installation
Add Esse and one of the official ES/OS clients to your Gemfile:
# Choose ONE of:gem 'elasticsearch' # Elasticsearch 1.x → 8.xgem 'opensearch-ruby' # OpenSearch 1.x → 2.x
gem 'esse'Then install:
bundle installOr install directly:
gem install esse elasticsearchGenerate the config file
Esse ships with a CLI to scaffold files. To generate a config file, run:
bundle exec esse installThis creates config/esse.rb. Esse automatically loads any of these paths:
Essefileconfig/esse.rbconfig/initializers/esse.rb
Configure a cluster
Edit the generated config to register your cluster(s):
require_relative '../environment' unless defined?(Rails)
Esse.configure do |config| config.indices_directory = 'app/indices'
config.cluster(:default) do |cluster| cluster.client = Elasticsearch::Client.new( url: ENV.fetch('ELASTICSEARCH_URL', 'http://localhost:9200') ) endendMultiple clusters are supported — see Configuration.
Generate an index class
bundle exec esse generate index UsersIndexThis creates app/indices/users_index.rb with placeholders for settings, mappings, and a repository.
Fill it in:
class UsersIndex < Esse::Index settings do { index: { number_of_shards: 2, number_of_replicas: 1 } } end
mappings do { properties: { name: { type: 'text' }, email: { type: 'keyword' }, created_at: { type: 'date' } } } end
repository :user do collection do |**context, &block| User.where(context).find_in_batches(batch_size: 1_000) do |batch| block.call(batch, context) end end
document do |user, **| { _id: user.id, name: user.name, email: user.email, created_at: user.created_at } end endendCreate and populate the index
Use the reset command to create the index, import data, and set up the alias:
bundle exec esse index reset UsersIndexThis performs a zero-downtime reset:
- Creates
users_<timestamp>with your settings/mappings. - Imports data from the repository.
- Points the
usersalias at the new index. - Removes the old concrete index.
Query the index
response = UsersIndex.search( body: { query: { match: { name: 'john' } } })
response.total # total hitsresponse.results # array of hit hashesresponse.each { |hit| puts hit['_source']['name'] }See Search for the full DSL.
Next steps
- Learn the Index DSL — settings, mappings, aliases, plugins.
- Understand Repositories — collections, serialization, lazy attributes.
- Explore the CLI — reset, import, create, update_aliases.
- Hook into Events for observability.
- Use an ORM extension like
esse-active_recordoresse-sequel.