CONCEPT Cited by 1 source
Nested document indexing¶
Definition¶
Nested document indexing is the Elasticsearch document
structure where a single top-level document carries a field
typed as nested whose values are an array of independently-
indexed child documents. Each child document's fields are
queried independently — a query expressing "child with field A
= x AND field B = y" matches only children where the same
child has both fields, not two separate children each with one
field.
Canonical wiki instance: Netflix's multimodal video-search index stores each temporal bucket as a nested document: "The root level captures the overarching asset context, while associated child documents house the specific, multi-modal annotation data. This hierarchical data model is precisely what empowers users to execute highly efficient, cross-annotation queries at scale" (Source: sources/2026-04-04-netflix-powering-multimodal-intelligence-for-video-search).
Why nested over flat¶
A flat document model (one row per annotation, asset + bucket denormalized on every row) works for simple queries but falls over on cross-annotation constraints within a single bucket:
- "find buckets where a character annotation has confidence > 0.8 AND a scene annotation has label='kitchen'" over a flat table can match across annotation rows in separate buckets.
- Nested documents keep each annotation as a self-contained
unit while grouping them under the parent bucket's
(asset_id, time_bucket)identity — so cross-field constraints apply within a single nested child.
The alternative — parent-child (separate indices) — trades query-performance for write-flexibility; nested is write-atomic and read-efficient but requires full-document reindexing on any change.
Schema shape (Netflix)¶
root document
├── associated_ids
│ ├── MOVIE_ID
│ └── ASSET_ID
├── time_bucket_start_ns
├── time_bucket_end_ns
└── source_annotations: [nested]
├── { annotation_id, annotation_type, label, time_range, ... }
└── { annotation_id, annotation_type, label, time_range, embedding_vector, ... }
Root carries the asset + bucket identity that's the upsert composite key. Child documents carry the per-annotation payload with heterogeneous field shapes across modalities.
Query expressiveness¶
The canonical query shape this enables:
"assets / buckets where a
CHARACTER_SEARCHannotation with label Joey co-occurs with aSCENE_SEARCHannotation with label kitchen"
Expressed as an Elasticsearch nested query with two bool
must clauses over the source_annotations field, this returns
precisely the buckets where both conditions are matched by
children of the same bucket.
Without the nested typing, the two clauses could match separate buckets glued by document boundaries — incorrect for the cross-annotation semantics.
Seen in¶
- sources/2026-04-04-netflix-powering-multimodal-intelligence-for-video-search — canonical wiki instance. Temporal bucket as parent, per-model annotations as nested children; shape explicitly motivated by cross-annotation multimodal query requirements.
Caveats¶
- Nested queries are more expensive than flat
term/matchqueries on Elasticsearch — each nested child is a separate Lucene document under the hood, and joins within a parent require the nested block join. - Updates to any nested child require reindexing the whole parent document (Elasticsearch doesn't support partial nested-child updates). Netflix's composite-key upsert shape implies full-document replacement on every model re-run.
- Sharding implications: asset-level data locality depends on the routing key; Netflix doesn't disclose routing strategy.
- Query-time cost of nested
inner_hitson large bucket populations is a known operational concern that the post doesn't address.