Skip to content

Add an experimental automatic retrieval path - #1110

Open
jwils wants to merge 3 commits into
mainfrom
joshuaw/docvalue-leaf-fetching
Open

Add an experimental automatic retrieval path#1110
jwils wants to merge 3 commits into
mainfrom
joshuaw/docvalue-leaf-fetching

Conversation

@jwils

@jwils jwils commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

Why

ElasticGraph should choose how to retrieve fields without asking schema authors to select datastore APIs. Narrow scalar queries may benefit from avoiding source retrieval.

What

Add an opt-in automatic retrieval experiment and benchmarks for both datastore APIs and complete GraphQL execution. Source retrieval remains the default.

How

Set graphql.experimental_field_retrieval: automatic after regenerating schema artifacts and verifying existing index mappings and data. The planner uses doc values only when every requested payload field is an eligible direct scalar. It preserves source fallback for mixed selections, lists, objects, highlighting, and unsupported mappings. Returnable data stays stored in _source.

A consuming project can compare both modes using its settings, queries, and variables. The GraphQL harness checks complete results and records which retrieval path ran. The standalone script compares _source, docvalue_fields, fields, and stored_fields without requiring a candidate library installation.

Risk

The default retrieval behavior is preserved, but query planning and response normalization are shared code. Automatic mode is experimental: current artifacts cannot verify historical physical mappings or data. Small-document or wide-selection queries may regress. The 100-field cap reflects the default datastore limit, not a measured performance cutoff.

Testing

Ran the standalone matrix twice on Elasticsearch 9.0.0. For 64 KiB source padding and 100 hits, source-free doc values reduced median client time by 12–22%. Mixed retrieval ranged from about 1% faster to 5% slower.

Also ran graphql_benchmark.rb twice against the repository's Widget schema, with 2,000 large-source documents, 100 hits, 20 warmups, and 100 samples per mode. Scalar-query median GraphQL execution time fell from 14.322 to 10.935 ms and from 13.511 to 10.378 ms (23–24%). Mixed queries used source in both modes and varied by roughly 1%. Complete results matched on every execution.

Usage and commands · Results, fixture details, and limitations

Bigger picture

Validate supported OpenSearch releases, representative consuming projects, and concurrent load before considering a default automatic policy. The exploratory OpenSearch snapshot results cover the standalone benchmark only. The design explains the roles of all four retrieval APIs.

Stack Info: Originally stacked on #1108 (merged); now targets main.

@jwils jwils changed the title Support for direct leaf fields Support retrieved_from: :doc_values for direct leaf fields Apr 6, 2026
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch 3 times, most recently from ad363a5 to a2b2407 Compare April 7, 2026 19:38
@jwils
jwils force-pushed the joshauw/fetchable-false-prototype branch from 8e9b12f to bde522d Compare April 7, 2026 19:42
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from a2b2407 to fdf2582 Compare April 7, 2026 19:46
@jwils
jwils force-pushed the joshauw/fetchable-false-prototype branch 4 times, most recently from caabea3 to fd1d61a Compare April 14, 2026 01:28
Base automatically changed from joshauw/fetchable-false-prototype to main April 14, 2026 01:49
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from fdf2582 to 83f0f4b Compare April 14, 2026 02:12
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 83f0f4b to 86787f5 Compare April 14, 2026 02:21
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 86787f5 to 8e29a0b Compare April 14, 2026 12:59
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 8e29a0b to f9afdfc Compare April 14, 2026 13:33
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from f9afdfc to 6e0529f Compare April 14, 2026 13:54
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 6e0529f to a006605 Compare April 14, 2026 14:13
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from a006605 to 4fe1200 Compare April 14, 2026 14:14
jwils added a commit that referenced this pull request Apr 14, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 4fe1200 to a6256d3 Compare April 14, 2026 14:32
@jwils
jwils marked this pull request as ready for review April 14, 2026 14:35

@myronmarston myronmarston left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

retrieved_from: :doc_values exposes a level of detail that, until now, we haven't exposed to ElasticGraph users. ElasticGraph does many things to query the data as efficiently as possible, without asking users to configure those things.

Can we do something similar here? For example, can we determine in which situations it's more efficient to use doc_values and automatically do so without requiring users to configure it at the field level?

Also, if we're going to change how fields are retrieved, I'd like to take a step back and review a full design that takes into account all the options Elasticsearch/OpenSearch offer us here. Besides _source and docvalue_fields there's also fields and stored_fields. I'd like to consider a unified design rather than just tacking this on as a one-off.

jwils added a commit that referenced this pull request Jun 16, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from a6256d3 to 9773e7e Compare June 16, 2026 22:54
jwils added a commit that referenced this pull request Jun 16, 2026
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 9773e7e to fb29671 Compare June 16, 2026 23:04
Add a narrow secondary retrieval path for fields that should stay
returnable in GraphQL while being excluded from stored `_source`.

When a field is marked `retrieved_from: :doc_values`, ElasticGraph:

- keeps the field in GraphQL output types
- excludes the field from datastore `_source` via `_source.excludes`
- requests the field through datastore `docvalue_fields`
- resolves the field from `fields` in datastore hits when `_source` omits it

The change is intentionally narrow: only direct, non-list, non-text
GraphQL leaf fields on indexed root document types are supported.
Query planning only uses `docvalue_fields` when every participating
index definition agrees on the retrieval method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from fb29671 to 055e57c Compare July 1, 2026 18:14
@jwils jwils changed the title Support retrieved_from: :doc_values for direct leaf fields Benchmark automatic field retrieval strategies Sep 10, 2026
@jwils jwils changed the title Benchmark automatic field retrieval strategies Add an experimental automatic retrieval path Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants