/ Query,
/ EngineHow query works?
#
A search request fans out from the coordinating node to every shard
copy of the target collections, executes against a snapshot of the
index, and merges ranked results back — this page walks that pipeline
and the mechanisms that keep it fast:
graph LR
R["search request"] --> C("coordinator")
C -->|"one copy per shard group —
saturated nodes are skipped"| G0("shard group 0 — any copy")
C --> G1("shard group 1 — any copy")
C --> G2("shard group 2 — any copy")
G0 --> Q["top-K + aggs against the snapshot —
mutable layer + immutable segments"]
G1 --> Q
G2 --> Q
Q --> M("merge — rank, dedupe, paginate")
M --> H["hits and aggregations,
or partial results on timeout"]
.../ Geo,
/ Bounding_box,
/ QueryGeo-bounding-box query
#
Matches documents whose geo_point field falls inside a rectangle
defined by its top-left and bottom-right corners. Coordinates are
WGS-84 degrees; filtering only (does not contribute distance scoring).
It is the cheapest geographic filter. When the region you need is a
rectangle of latitude and longitude — a map viewport, a city’s extents,
a country’s outline approximated by its bounds — the engine answers
with a single index range and no per-document geometry math.
.../ Match,
/ QueryMatch query
#
Returns documents that match a provided text, number, date or boolean
value. The provided text is analyzed before matching — this is the
primary full-text query.
Inside a
nested query: supported — the text is matched per array element.
How it works
#
The engine resolves the analyzer first — the analyzer parameter when
given, else the field’s search analyzer, else the built-in standard
analyzer — and runs it over the query text. Each resulting token becomes
one term clause:
.../ Nested,
/ QueryNested query
#
Matches parent documents whose nested sub-documents — objects mapped
with "nested": true — satisfy a query within one element at a time.
It exists because a flattened object index cannot keep two field values
inside the same array element together — the pitfall the next section
makes concrete.
The cross-element problem
#
A flattened index correlates across array elements, not within them:
variants.color = blue AND variants.size = L matches a document as soon
as some element is blue and some element is L — not necessarily the
same one. The teaching dataset’s products makes the difference visible
(each element pairs blue with L, never with M):
.../ Term,
/ QueryTerm query
#
Returns documents that contain an exact term in a provided field.
You can use the term query to find documents based on a precise value such as a
price, a product ID, or a username. It is also the atom the rest of the
term-level family resolves to:
terms expands into a should of
term clauses, and prefix / wildcard / regexp / fuzzy all resolve to term
sets before execution.
.../ Geo,
/ Distance,
/ QueryGeo-distance query
#
Matches documents whose geo_point field lies within a great-circle
distance of a centre point. Distances are in metres.
This is the “find me things nearby” query: given one centre and one
radius, it returns exactly the documents inside that disc on the
sphere — the shape behind store locators, delivery zones and proximity
alerts.
How it works
#
The field is the same two-dimensional (lat, lon) BKD tree the other
geo queries use (points indexed in any of the three ingest forms —
object, [lon, lat] array, "lat,lon" string). Execution is
two-phase:
.../ Join,
/ QueryJoin query
#
Status: functional (semi-join). Joins need a running node — the
gateway orchestrates and the engine executes, which is why the wasm
playground does not host them. The
joins tutorial walks the complete relational
sequence — references → join → FK-routed writes → salting →
?routing= addressing — step by step against a live node.
Matches documents in the outer collection — the one in the request
URL — whose field values intersect the join_on values of documents
matching a query on the inner collection — the one named by
target. The result is a semi-join: outer documents that have at least
one matching inner document, each reported once. It is the moral
equivalent of SQL’s
.../ Multi_vector,
/ Fusion,
/ QueryMulti-vector query
#
Executes several
vector queries — each targeting a
(potentially different) vector field — and fuses their results into one
ranking.
One document often has more than one useful representation: a title
embedding and a body embedding, a dense vector and a learned-sparse
vector, an image embedding beside its caption. A single vector query
can read only one of them; this query runs them all and merges the
rankings.
.../ Phrase,
/ QueryPhrase query
#
Returns documents that contain the exact sequence of terms, in order,
with no other terms in between (modulo slop). The text is analyzed
before matching, like the
match query.
The query’s native name is phrase; the match_phrase spelling
deserializes to the same query — an accepted alias, not
a different feature.
Inside a
nested query: supported — the phrase, including its slop, must be satisfied by ONE array element; terms keep query order.
...
/ Terms,
/ QueryTerms query
#
Returns documents that contain one or more exact terms in a provided
field. Equivalent to a boolean should of individual
term queries — a document matches if it contains any
of the values.
Inside a
nested query: not supported yet — the clause is rejected with an HTTP 400 naming the offending clause. Expand into a bool should of
term clauses instead.
How it works
#
The planner expands the query before execution: each value becomes a
term clause inside a BooleanQuery with
minimum_should_match: 1, and a single-value terms collapses straight
into one bare term query. Everything said on the
term page
about verbatim lookup, index routing (dictionary for keyword/text, BKD for
numeric/date, Bool column for boolean) and BM25 scoring therefore applies
per value here, with the per-value scores OR-ed together.
...