Search with the Query DSL
Start with the kind of match you need: words, an exact value, a range or a combination. A query DSL is a JSON structure that describes those conditions. The examples below show where each condition belongs.
Use the supported dedicated Elasticsearch-compatible endpoint. JavaScript 7.x client payloads belong in body and responses are read from body; a standalone JSON fragment is the request body.
- Choose words or exact valuesMatch text with a search query or exact fields with filters.
- Combine the conditionsSeparate relevance conditions from required restrictions.
- Set order and page sizeRequest a bounded, predictable set of hits.
- Inspect matches and totalsCheck whether the result answers the original question.
Full-text: match and match_phrase
match analyzes your terms the same way the field was analyzed and ranks by BM25. match_phrase keeps the words adjacent.
query: { match: { description: 'waterproof jacket' } }
// only this exact phrase, in this order
query: { match_phrase: { description: 'waterproof jacket' } }Exact: term and terms
Use these on keyword, numeric, date and boolean fields. On an analyzed text field a term query looks for a single analyzed token, which is rarely what you want.
query: { term: { brand: 'Aero' } }
query: { terms: { brand: ['Aero', 'Metro'] } }Ranges
query: { range: { price: { gte: 50, lt: 200 } } }
query: { range: { added: { gte: '2026-09-01T00:00:00Z' } } }Combining: bool
must contributes to the score, filter does not (and is the one to use for exact predicates), should boosts, must_not excludes.
query: { bool: {
must: [{ match: { name: 'marathon' } }],
filter: [{ term: { brand: 'Aero' } },
{ range: { price: { lte: 200 } } }],
should: [{ match: { description: 'carbon' } }],
must_not: [{ term: { discontinued: true } }]
} }Typo tolerance
Fuzziness walks the words actually indexed in the field. For a search box, pair it with the suggester so you can show what you corrected to.
query: { match: { name: { query: 'marathn', fuzziness: 'AUTO' } } }Sorting, paging and trimming the response
sort: [{ price: 'desc' }, '_score'],
from: 0, size: 20,
_source: ['name', 'price'] // only these fields come backUse search_after with the sort values of the last hit for sorted pagination. Scroll and Point-in-Time (PIT) are also supported. Check /v1/capabilities for the deployment limits and keep cursor lifetimes bounded.
Reading one document
When you know the id, skip the search. The version that comes back is the one the write reported, so you can carry it into a conditional write.
await es.get({ index: 'shop.products', id: 'sku-8842' })
await es.exists({ index: 'shop.products', id: 'sku-8842' }) // true / false
await es.mget({ index: 'shop.products', body: { ids: ['a','b'] } })What a missing index does
A search or count against an index that does not exist answers 404 index_not_found_exception, the same as a real cluster. An index that exists but holds nothing answers 200 with zero hits. Those are different answers on purpose: a client polling for an index can tell absent from empty.
Security is part of the query
Row-level security and column masking are enforced on the search itself. A caller who cannot see a row will not find it through any query, and a query that searches a masked column is refused rather than answered — otherwise the match set could be used to reconstruct the value the mask hides.
-
Summarise results — Terms, metrics, date histograms, filter buckets and top hits.
-
Copy-paste recipes — Sixteen worked requests with their responses.
Elasticsearch is a trademark of Elasticsearch B.V., registered in the U.S. and in other countries. OriginChainDB is not affiliated with, endorsed by, or sponsored by Elasticsearch B.V. OriginChainDB implements a compatible HTTP API so that existing Elasticsearch clients can talk to it; it does not distribute Elasticsearch software.