Skip to content

Commit 402d489

Browse files
authored
[docs] Add dagster-elasticsearch integration reference (#33860)
## Summary Adds a community-supported integration reference for `dagster-elasticsearch` <img width="1378" height="1358" alt="image" src="https://github.com/user-attachments/assets/bc243e56-41f4-45f3-babc-5187db3a6500" /> ## Changelog - [docs] Added documentation for community integration `dagster-elasticsearch`
1 parent 5100b58 commit 402d489

6 files changed

Lines changed: 264 additions & 32 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
title: Dagster & Elasticsearch
3+
sidebar_label: Elasticsearch
4+
sidebar_position: 1
5+
description: The community-supported Elasticsearch integration provides a resource for interacting with Elasticsearch clusters and an IO manager for bulk-indexing Dagster asset outputs as searchable documents.
6+
tags: [community-supported, storage]
7+
source: https://github.com/dagster-io/community-integrations/tree/main/libraries/dagster-elasticsearch
8+
pypi: https://pypi.org/project/dagster-elasticsearch/
9+
sidebar_custom_props:
10+
logo: images/integrations/elasticsearch.svg
11+
community: true
12+
partnerlink: https://www.elastic.co/elasticsearch
13+
---
14+
15+
import CommunityIntegration from '@site/docs/partials/\_CommunityIntegration.md';
16+
17+
<CommunityIntegration />
18+
19+
<p>{frontMatter.description}</p>
20+
21+
## Installation
22+
23+
<PackageInstallInstructions packageName="dagster-elasticsearch" />
24+
25+
Optional extras are available for table-like asset outputs. Install the extras that match the data types your assets return:
26+
27+
<PackageInstallInstructions packageName="dagster-elasticsearch[pandas]" />
28+
29+
<PackageInstallInstructions packageName="dagster-elasticsearch[polars]" />
30+
31+
<PackageInstallInstructions packageName="dagster-elasticsearch[arrow]" />
32+
33+
The underlying `elasticsearch` Python client must match the major version of your Elasticsearch cluster. Pin the client major version in your project if needed, for example `elasticsearch>=8.10,<9` for Elasticsearch 8.x.
34+
35+
## Example
36+
37+
<CodeExample path="docs_snippets/docs_snippets/integrations/elasticsearch.py" language="python" />
38+
39+
## Using the Elasticsearch resource
40+
41+
Use `ElasticsearchResource` when an asset or op needs direct access to an Elasticsearch client. Configure it with either:
42+
43+
- `HostsConfig` for self-hosted or generic Elasticsearch endpoints
44+
- `CloudConfig` for Elastic Cloud deployments
45+
46+
Both configuration types support API-key authentication or basic authentication with a username and password. `HostsConfig` also supports bearer auth, certificate authorities, and certificate verification settings.
47+
48+
## Using the Elasticsearch IO manager
49+
50+
Use `ElasticsearchIOManager` to bulk-index asset outputs into Elasticsearch. It supports outputs such as dictionaries, lists of dictionaries, pandas DataFrames, Polars DataFrames or LazyFrames, and PyArrow tables. The `id_field` option, which defaults to `_id`, is used as the Elasticsearch document ID when present.
51+
52+
Common IO manager options include:
53+
54+
| Option | Description |
55+
| ----------------- | ------------------------------------------------------------------------- |
56+
| `index` | Target index name. When `use_alias=True`, this is the stable alias name. |
57+
| `bulk_chunk_size` | Number of documents per bulk request. |
58+
| `max_chunk_bytes` | Optional maximum bulk request size in bytes. |
59+
| `refresh` | Whether to refresh the index after writes. |
60+
| `lazy_load` | Return an iterator from `load_input` instead of loading all hits eagerly. |
61+
| `scan_size` | Page size for scroll-based reads. |
62+
63+
Most IO manager settings can be overridden for individual assets with asset metadata, including `index`, `id_field`, `bulk_chunk_size`, `max_chunk_bytes`, `refresh`, `rollover_strategy`, and `index_config`.
64+
65+
## Alias rollover
66+
67+
Set `use_alias=True` to write each materialization to a fresh physical index and atomically swap a stable alias to the new index. This lets readers and downstream assets query the alias while avoiding partial updates.
68+
69+
Rollover strategies include:
70+
71+
| Strategy | Behavior |
72+
| ----------- | --------------------------------------------------------------------- |
73+
| `auto` | Uses the partition key for partitioned assets, otherwise a timestamp. |
74+
| `timestamp` | Appends a UTC timestamp suffix. |
75+
| `run_id` | Appends the Dagster run ID. |
76+
| `partition` | Appends a slugified partition key. |
77+
| `none` | Uses no suffix. |
78+
79+
Use `keep_last` to delete older rollover indices after successful alias swaps.
80+
81+
## Asset checks
82+
83+
The IO manager records materialization metadata such as `index`, `indexed`, `failures`, and `alias`. Use `build_indexed_asset_check` to assert that a materialization indexed at least a minimum number of documents and did not exceed a maximum failure count.
84+
85+
## About Elasticsearch
86+
87+
Elasticsearch is a distributed search and analytics engine for indexing, searching, and analyzing large volumes of data in near real time. Learn more in the [Elasticsearch documentation](https://www.elastic.co/docs/solutions/search).
Lines changed: 7 additions & 0 deletions
Loading
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from dagster_elasticsearch import (
2+
ElasticsearchIOManager,
3+
ElasticsearchResource,
4+
HostsConfig,
5+
build_indexed_asset_check,
6+
)
7+
8+
import dagster as dg
9+
10+
11+
@dg.asset(compute_kind="elasticsearch")
12+
def indexed_doc(es: ElasticsearchResource) -> None:
13+
with es.get_client() as client:
14+
client.index(index="docs", id="hello", document={"title": "hello"})
15+
client.indices.refresh(index="docs")
16+
17+
18+
@dg.asset(io_manager_key="elasticsearch_io_manager")
19+
def search_docs() -> list[dict[str, str]]:
20+
return [
21+
{"_id": "1", "title": "hello"},
22+
{"_id": "2", "title": "world"},
23+
]
24+
25+
26+
@dg.definitions
27+
def defs() -> dg.Definitions:
28+
return dg.Definitions(
29+
assets=[indexed_doc, search_docs],
30+
asset_checks=[build_indexed_asset_check(asset=search_docs, min_indexed=1)],
31+
resources={
32+
"es": ElasticsearchResource(
33+
connection_config=HostsConfig(
34+
hosts=["https://es.example.com:9200"],
35+
api_key=dg.EnvVar("ELASTICSEARCH_API_KEY"),
36+
),
37+
),
38+
"elasticsearch_io_manager": ElasticsearchIOManager(
39+
connection_config=HostsConfig(
40+
hosts=["https://es.example.com:9200"],
41+
api_key=dg.EnvVar("ELASTICSEARCH_API_KEY"),
42+
),
43+
index="docs",
44+
use_alias=True,
45+
rollover_strategy="auto",
46+
keep_last=3,
47+
),
48+
},
49+
)

examples/docs_snippets/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ test = [
121121
"opentelemetry-sdk",
122122
"pytest_httpserver",
123123
# Community integrations
124+
"dagster-elasticsearch @ git+https://github.com/dagster-io/community-integrations.git#subdirectory=libraries/dagster-elasticsearch",
124125
"dagster-iceberg @ git+https://github.com/dagster-io/community-integrations.git#subdirectory=libraries/dagster-iceberg",
125126
]
126127
test-docs-snapshot = [

examples/docs_snippets/tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ commands =
3333
# install cloud packages out of band due to version conflicts between pypi and source
3434
all: uv pip install dagster-cloud --no-deps
3535
all: uv pip install path
36-
all: /bin/bash -c '! uv pip list --exclude-editable | grep -e dagster | grep -v -e dagster-cloud -e dagster-iceberg'
36+
all: /bin/bash -c '! uv pip list --exclude-editable | grep -e dagster | grep -v -e dagster-cloud -e dagster-iceberg -e dagster-elasticsearch'
3737
all: pytest -vv {posargs} --ignore=docs_snippets_tests/test_integration_files_load.py --ignore=docs_snippets_tests/snippet_checks
3838

3939
integrations: uv pip install dagster-cloud-cli --no-deps
4040
integrations: uv pip install dagster-cloud --no-deps
4141
integrations: uv pip install path
42-
integrations: /bin/bash -c '! uv pip list --exclude-editable | grep -e dagster | grep -v -e dagster-cloud -e dagster-iceberg'
42+
integrations: /bin/bash -c '! uv pip list --exclude-editable | grep -e dagster | grep -v -e dagster-cloud -e dagster-iceberg -e dagster-elasticsearch'
4343
integrations: pytest -vv {posargs} docs_snippets_tests/test_integration_files_load.py
4444

4545
docs_snapshot_test: sh ./docs_snippets_tests/ensure_snapshot_deps.sh

0 commit comments

Comments
 (0)