Range, Exists, IDs, Prefix and Wildcard
Match and term cover most searches, but the bookshop also asks "books between 10 and 20", "books missing a price", "books 1 and 4", and "authors starting with Mi". Each has its own small leaf query, and each is easy once you know what it compares against.
The rule
Range compares, exists checks presence, ids fetches by key, prefix and wildcard match patterns.
Range — numbers, dates and keywords between bounds, with gt, gte, lt, lte:
{ "query": { "range": { "price": { "gte": 10, "lte": 20 } } } }
{ "query": { "range": { "published": { "gte": "2020-01-01", "lt": "now" } } } }Exists — documents that have at least one indexed, non-null value in the field:
{ "query": { "exists": { "field": "price" } } }A document where price is missing, null or an empty array [] does not match. Wrap it in must_not (next section) to find the ones without a price.
IDs — fetch documents by their _id:
{ "query": { "ids": { "values": [ "1", "4" ] } } }Prefix — keyword values that start with the given characters, case-sensitive:
{ "query": { "prefix": { "author": "Mi" } } }Wildcard — a pattern where * means any run of characters (including none) and ? means exactly one character:
{ "query": { "wildcard": { "isbn": "978-1-23?-*" } } }Two warnings. Prefix and wildcard do not analyse your input, so on a text field they test single stored words, not the whole string; aim them at keyword fields. And a pattern that starts with * forces Elasticsearch to check every term in the field — slow on big indices.
The shortcut
Turn the English into one of five shapes: "between" → range, "has a" → exists, "these exact records" → ids, "starts with" → prefix, "looks like" → wildcard.
"Books from 10 to 20, both included"
"between" →
rangewithgte: 10andlte: 20.
Drills
Answer fast — trust the rule.
Which range finds books priced over 10 but strictly under 20?
Which document does {"exists": {"field": "price"}} match?
What does the wildcard pattern Mi?a* match on a keyword field?
Why is {"wildcard": {"author": "*Das"}} a concern on a large index?
Remember
- Range compares, exists checks presence, ids fetches by key, prefix and wildcard match patterns.
- between → range, has a → exists, exact records → ids, starts with → prefix, looks like → wildcard.
- Aim prefix and wildcard at keyword fields and avoid a leading
*.
