Skip to content

Add an experimental automatic retrieval path - #1110

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

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

Conversation

@jwils

@jwils jwils commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

Why

ElasticGraph should choose efficient field retrieval 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, comparison harnesses, and a read-only compatibility preflight. Source retrieval remains the default, and returnable data stays stored in _source.

How

The GraphQL instance injects a source or automatic planner through the query builder. It plans against the final merged selection. Extensions can wrap it per instance, while document normalization keeps field resolvers independent of retrieval APIs.

Automatic mode uses doc values only when every requested payload field is an eligible direct scalar. Mixed selections, lists, objects, highlighting, unsupported mappings, and requests exceeding 100 fields retain source retrieval.

Before opting in, regenerate artifacts and run verify_indices.rb with the application's settings. It checks queryable physical indices, all matching rollover generations, and templates. Then validate historical data and compare complete GraphQL results using representative application queries. The benchmark and preflight checks now run explicitly in the supported-datastore CI jobs.

Risk

Shared query planning and response normalization change in both modes. The preflight checks current mappings and settings; it cannot prove historical data compatibility. Small-document or wide-selection queries may regress. The 100-field cap is a request limit, not a measured performance cutoff.

Testing

Before this rebase, the full suite passed: 5,143 examples, zero failures, and 100% line and branch coverage. All 14 retrieval acceptance, GraphQL harness, and live preflight checks passed on Elasticsearch 9.0.0/9.4.2 and OpenSearch 2.19.0/3.6.0. After rebasing, type checking, lint, spellcheck, and schema/configuration artifact verification passed.

The September 10 standalone benchmark ran twice on Elasticsearch 9.0.0. With 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.

The GraphQL harness also ran twice against 2,000 large-source Widget documents, with 100 hits, 20 warmups, and 100 samples per mode. Scalar-query median execution time fell by 23–24%; complete results matched on every execution. These fixture-specific results do not establish a production policy.

Usage and commands · Results and limitations

Bigger picture

The rollout defines application qualification, canary stages, rollback thresholds, and graduation criteria. No consuming application has qualified for production yet. A default automatic policy requires maintained physical compatibility information and repeatable workload-level gains under concurrency. Keep storage reduction separate.

The design explains the roles of all four retrieval APIs and the planner's place in the resolver-built query pipeline.

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
jwils added a commit that referenced this pull request Jul 1, 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 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
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 3480741 to 644fab8 Compare September 12, 2026 18:01
Plan retrieval against the final merged query through an instance-scoped strategy, keeping source retrieval as the default and preserving stored source.

Add compatibility verification, supported-backend checks, benchmark tooling, and explicit application qualification and rollout gates.
@jwils
jwils force-pushed the joshuaw/docvalue-leaf-fetching branch from 644fab8 to 9c6c522 Compare September 12, 2026 18:25
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