Terms 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
nestedquery: not supported yet — the clause is rejected with an HTTP 400 naming the offending clause. Expand into aboolshouldoftermclauses 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.
Like term, the values are matched as exact terms — no analysis is
applied. Note the engine’s terms has no case_insensitive knob (its
term sibling does); fold case yourself before sending if you need it.
One internal fast path is worth knowing about: when a terms set was
produced by a join rewrite (the _ref payload) rather than
hand-written, the executor may run it as a sorted-intersect over the
value-sorted doc-values column instead of one iterator per value. Scores
are irrelevant on that path; hand-written queries keep the per-term
scoring semantics described above.
Examples #
The following search matches the two noisiest levels together — 50 of
the 150 documents in the logs dataset (25 error + 25 warn).
POST /my-collection/_search
{
"query": {
"terms": {
"field": "status",
"values": ["published", "pending"]
}
}
}
Use cases #
- Multi-select facets. A dashboard checkbox set (“error + warn”, three
of four sales statuses) maps one-to-one onto a
valuesarray — the SQL twin is anIN (...)list. - Cohort sets.
termsoncustomers.tier = ["gold","silver"]returns 12 of the 20 customers; onarticles.tags = ["search","storage"]it returns the 4 articles carrying either tag. - Host shards.
termsonlogs.host = ["web-01","web-02"]scopes an investigation to 100 of the 150 log lines. - Filter step of a two-phase search. A
bool.filtertermsnarrowing candidates before a scored full-text clause — the cheapest possible shape since per-value scoring is discarded anyway.
Parameters for terms
#
field
(Required, string) The field to match.values
(Required, array) List of terms to match. A document matches if it contains any of these values.boost
(Optional, float, default:1.0) Decrease or increase the relevance scores of the query.
Notes #
The values are matched as exact terms — no analysis is applied. To
match analyzed text, use the
match query.
Related #
term— the single-value original this expands into.bool— what the expansion becomes; write it by hand when you needmust_notor per-clause boosts around the values.range— the contiguous-family alternative when the values form an interval.termsaggregation — count documents per value of the same keyword field atermsquery filters on; the pair powers faceted navigation.