Esse is a pure Ruby, framework-agnostic ElasticSearch/OpenSearch client gem that provides an ETL (Extract, Transform, Load) architecture for managing search indices.
It is built on top of the official elasticsearch-ruby and opensearch-ruby clients.
Documentation Index
Core Concepts
| Guide | Description |
|---|---|
| Getting Started | Installation, configuration and your first index |
| Configuration | Global config and cluster management |
| Index | Defining indices, settings, mappings, lifecycle |
| Repository | Data loading through collections and documents |
| Document | Document classes and variants |
| Collection | Iterating over data sources |
| Search | Query DSL, response wrapping, scrolls |
| Import | Bulk import pipeline, retries, batching |
| Transport | Low-level ES/OS client wrapper |
| Events | Pub/sub and instrumentation |
| Plugins | Plugin system and how to write custom plugins |
| CLI | esse command-line reference |
| Errors | Exception hierarchy |
Ecosystem
| Extension | Purpose |
|---|---|
| esse-active_record | ActiveRecord integration |
| esse-sequel | Sequel ORM integration |
| esse-rails | Rails instrumentation |
| esse-async_indexing | Background indexing (Sidekiq/Faktory) |
| esse-hooks | Hook/callback state management |
| esse-jbuilder | Jbuilder-based search templates |
| esse-kaminari | Kaminari pagination |
| esse-pagy | Pagy pagination |
See extensions.md for the complete list.
Architecture Overview
Esse is structured around three core components that form an ETL pipeline:
Collection (yields batches of raw objects) ↓Repository (serializes batches → Documents) ↓Import pipeline (builds bulk requests with retries) ↓Transport (sends bulk to ES/OS)Core Components
- Index (
Esse::Index) — defines settings, mappings, aliases, and orchestrates operations. - Repository (
Esse::Repository) — declarescollectionanddocument, one index may have many. - Document (
Esse::Document) — a single indexable document withid,type,routing,source,meta.
Supporting Components
- Cluster — ES/OS client connections, index prefix, readonly mode.
- Transport — wraps the official client with consistent error handling.
- Search — query DSL builder with response wrapping and scroll support.
- Events — pub/sub instrumentation for every ES/OS operation.
- CLI — Thor-based CLI (
esse install,esse generate,esse index *). - Plugins — extension system loaded via
plugin :name.
Quick Example
Esse.configure do |config| config.cluster(:default) do |cluster| cluster.client = Elasticsearch::Client.new(url: ENV['ELASTICSEARCH_URL']) endend
# app/indices/users_index.rbclass UsersIndex < Esse::Index settings do { index: { number_of_shards: 2, number_of_replicas: 1 } } end
mappings do { properties: { name: { type: 'text' }, email: { type: 'keyword' } } } end
repository :user do collection do |**ctx, &block| User.find_in_batches(batch_size: 1000) { |batch| block.call(batch, ctx) } end
document do |user, **| { _id: user.id, name: user.name, email: user.email } end endend
# Use:UsersIndex.create_index(alias: true)UsersIndex.importUsersIndex.search(q: 'john').resultsVersion
Current version: 0.4.0
Requires Ruby >= 2.7 and one of:
elasticsearch(any version from 1.x to 8.x)opensearch(any version from 1.x to 2.x)
License
MIT — see LICENSE.txt.