Add an experimental automatic retrieval path - #1110
Conversation
retrieved_from: :doc_values for direct leaf fields
ad363a5 to
a2b2407
Compare
8e9b12f to
bde522d
Compare
a2b2407 to
fdf2582
Compare
caabea3 to
fd1d61a
Compare
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>
fdf2582 to
83f0f4b
Compare
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>
83f0f4b to
86787f5
Compare
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>
86787f5 to
8e29a0b
Compare
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>
8e29a0b to
f9afdfc
Compare
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>
f9afdfc to
6e0529f
Compare
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>
6e0529f to
a006605
Compare
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>
a006605 to
4fe1200
Compare
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>
4fe1200 to
a6256d3
Compare
myronmarston
left a comment
There was a problem hiding this comment.
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.
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>
a6256d3 to
9773e7e
Compare
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>
9773e7e to
fb29671
Compare
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>
fb29671 to
055e57c
Compare
retrieved_from: :doc_values for direct leaf fields3480741 to
644fab8
Compare
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.
644fab8 to
9c6c522
Compare
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.rbwith 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.