Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ This gem is a Ruby simple and extremely flexible client for ElasticSearch and Op
- [esse-redis_storage](https://github.com/marcosgz/esse-redis_storage) - Add-on for the esse gem to be used with Redis as a storage backend
- [esse-async_indexing](https://github.com/marcosgz/esse-async_indexing) - Esse extension to allow async indexing using Faktory or Sidekiq.

## Documentation

Full guides, recipes, and API reference are published at **[gems.marcosz.com.br/esse](https://gems.marcosz.com.br/esse/)** — part of the [marcosgz Ruby gem catalogue](https://gems.marcosz.com.br).

## Components

The main idea of the gem is to be compatible with any type of datasource. It means that you can use it with ActiveRecord, Sequel, HTTP APIs, or any other data source. The gem is divided into three main components:
Expand Down
121 changes: 121 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Esse Documentation

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`](https://github.com/elastic/elasticsearch-ruby) and [`opensearch-ruby`](https://github.com/opensearch-project/opensearch-ruby) clients.

## Documentation Index

### Core Concepts

| Guide | Description |
|-------|-------------|
| [Getting Started](getting-started.md) | Installation, configuration and your first index |
| [Configuration](configuration.md) | Global config and cluster management |
| [Index](index.md) | Defining indices, settings, mappings, lifecycle |
| [Repository](repository.md) | Data loading through collections and documents |
| [Document](document.md) | Document classes and variants |
| [Collection](collection.md) | Iterating over data sources |
| [Search](search.md) | Query DSL, response wrapping, scrolls |
| [Import](import.md) | Bulk import pipeline, retries, batching |
| [Transport](transport.md) | Low-level ES/OS client wrapper |
| [Events](events.md) | Pub/sub and instrumentation |
| [Plugins](plugins.md) | Plugin system and how to write custom plugins |
| [CLI](cli.md) | `esse` command-line reference |
| [Errors](errors.md) | Exception hierarchy |

### Ecosystem

| Extension | Purpose |
|-----------|---------|
| [esse-active_record](../../esse-active_record/docs/README.md) | ActiveRecord integration |
| [esse-sequel](../../esse-sequel/docs/README.md) | Sequel ORM integration |
| [esse-rails](../../esse-rails/docs/README.md) | Rails instrumentation |
| [esse-async_indexing](../../esse-async_indexing/docs/README.md) | Background indexing (Sidekiq/Faktory) |
| [esse-hooks](../../esse-hooks/docs/README.md) | Hook/callback state management |
| [esse-jbuilder](../../esse-jbuilder/docs/README.md) | Jbuilder-based search templates |
| [esse-kaminari](../../esse-kaminari/docs/README.md) | Kaminari pagination |
| [esse-pagy](../../esse-pagy/docs/README.md) | Pagy pagination |

See [extensions.md](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`) — declares `collection` and `document`, one index may have many.
- **Document** (`Esse::Document`) — a single indexable document with `id`, `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

```ruby
# config/esse.rb
Esse.configure do |config|
config.cluster(:default) do |cluster|
cluster.client = Elasticsearch::Client.new(url: ENV['ELASTICSEARCH_URL'])
end
end

# app/indices/users_index.rb
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' }
} }
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
end
end

# Use:
UsersIndex.create_index(alias: true)
UsersIndex.import
UsersIndex.search(q: 'john').results
```

## Version

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](../LICENSE.txt).
211 changes: 211 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# CLI

Esse ships with a Thor-based CLI called `esse`. It handles scaffolding, index lifecycle, and bulk operations.

## Running

```bash
bundle exec esse <command> [options]
```

Or as a standalone executable:

```bash
gem install esse
esse <command>
```

## Global options

| Flag | Description |
|------|-------------|
| `--require FILE`, `-r FILE` | Require a file before executing (useful for a custom config) |
| `--silent`, `-s` | Suppress event output |
| `--version`, `-v` | Print version |
| `--help` | Print help |

## Configuration paths

The CLI auto-loads the first existing file from:

1. `Essefile`
2. `config/esse.rb`
3. `config/initializers/esse.rb`

In a Rails app, add `require 'esse/rails'` (via the [esse-rails](../../esse-rails/docs/README.md) gem) and the Rails environment is loaded automatically.

## Commands

### `esse install`

Generate a configuration file template:

```bash
bundle exec esse install
bundle exec esse install --path config/my_esse.rb
```

Options:

| Flag | Default | Description |
|------|---------|-------------|
| `--path` / `-p` | `config/esse.rb` | Target path |

### `esse generate index <CLASS_NAME>`

Scaffold a new index class:

```bash
bundle exec esse generate index UsersIndex
```

Creates `app/indices/users_index.rb` (or wherever `Esse.config.indices_directory` points) with a template.

---

### `esse index reset <INDEX_CLASS>`

Zero-downtime index reset — create a new concrete index, import data, swap the alias, and remove the old one.

```bash
bundle exec esse index reset UsersIndex --suffix 20240401 --optimize
```

| Option | Default | Description |
|--------|---------|-------------|
| `--suffix` | timestamp | Concrete index suffix |
| `--import` | `true` | Import from collection |
| `--reindex` | `false` | Use ES `_reindex` API instead of importing |
| `--optimize` | `true` | Temporarily drop replicas/refresh for faster bulk |
| `--settings` | — | JSON/hash to override index settings |
| `--preload_lazy_attributes` | — | Preload lazy attributes via search before import |
| `--eager_load_lazy_attributes` | — | Resolve lazy attributes during bulk |
| `--update_lazy_attributes` | — | Partial-update lazy attributes after bulk |

### `esse index create <INDEX_CLASS>`

Create an index without importing:

```bash
bundle exec esse index create UsersIndex --alias
```

| Option | Default | Description |
|--------|---------|-------------|
| `--suffix` | — | Concrete suffix |
| `--alias` | `false` | Also create the alias pointing at the index |
| `--settings` | — | Override settings |

### `esse index delete <INDEX_CLASS>`

```bash
bundle exec esse index delete UsersIndex --suffix 20240401
```

### `esse index import <INDEX_CLASS>`

```bash
bundle exec esse index import UsersIndex \
--repo user \
--context active:true,region:us \
--suffix 20240401
```

| Option | Description |
|--------|-------------|
| `--repo` | Specific repository (omit to import all) |
| `--suffix` | Target index suffix |
| `--context` | Context hash for collection filtering |
| `--preload_lazy_attributes` | Preload via search |
| `--eager_load_lazy_attributes` | Resolve during bulk |
| `--update_lazy_attributes` | Refresh as partial updates |

### `esse index open <INDEX_CLASS>` / `esse index close <INDEX_CLASS>`

Open or close the index:

```bash
bundle exec esse index close UsersIndex
bundle exec esse index open UsersIndex
```

### `esse index update_aliases <INDEX_CLASS>`

Point the alias at one or more concrete indices:

```bash
bundle exec esse index update_aliases UsersIndex --suffix 20240401
bundle exec esse index update_aliases UsersIndex --suffix v1,v2
```

### `esse index update_settings <INDEX_CLASS>`

```bash
bundle exec esse index update_settings UsersIndex --settings number_of_replicas:2
```

### `esse index update_mapping <INDEX_CLASS>`

```bash
bundle exec esse index update_mapping UsersIndex
bundle exec esse index update_mapping UsersIndex --suffix 20240401
```

### `esse index update_lazy_attributes <INDEX_CLASS> <attr> [attr ...]`

Refresh specific lazy attributes without a full reindex:

```bash
bundle exec esse index update_lazy_attributes UsersIndex comment_count follower_count \
--repo user \
--context active:true
```

| Option | Description |
|--------|-------------|
| `--repo` | Repository name (required when multiple) |
| `--suffix` | Target suffix |
| `--context` | Collection context |
| `--bulk_options` | Extra ES bulk options |

## Extension commands

Gems like [esse-async_indexing](../../esse-async_indexing/docs/README.md) add more subcommands:

```bash
bundle exec esse index async_import UsersIndex --service sidekiq
bundle exec esse index async_update_lazy_attributes UsersIndex comment_count --service sidekiq
```

Consult each extension's documentation for details.

## Exit codes

- `0` — success
- non-zero — any error

Use `--silent` in CI to reduce noise.

## Example workflows

### First-time bootstrap

```bash
bundle exec esse install
# edit config/esse.rb
bundle exec esse generate index UsersIndex
# edit app/indices/users_index.rb
bundle exec esse index reset UsersIndex
```

### Daily reindex via cron

```bash
bundle exec esse index reset UsersIndex --suffix $(date +%Y%m%d) --optimize
```

### Partial refresh

```bash
bundle exec esse index update_lazy_attributes UsersIndex comment_count
```
Loading
Loading