Elasticsearch Search API

Four major search conditions

Elasticsearch Query DSL provides match, term, range, and bool queries. Results can also be ordered with sort.

Prepare sample documents

POST /_bulk
{ "index": { "_index": "demo_search", "_id": "1" }}
{ "text": "This is Elasticsearch test." }
{ "index": { "_index": "demo_search", "_id": "2" }}
{ "text": "Elasticsearch is God." }
{ "index": { "_index": "demo_search", "_id": "3" }}
{ "text": "This is a pen." }

GET /demo_search/_search without a condition returns all three documents.

1. Match queries

match performs full-text search against analyzed terms.

GET /demo_search/_search
{"query":{"match":{"text":"Elasticsearch"}}}

This returns documents 1 and 2. Multiple terms default to OR; specify AND when all terms are required:

GET /demo_search/_search
{"query":{"match":{"text":{"query":"Elasticsearch test","operator":"AND"}}}}

match_phrase additionally requires term order. Elasticsearch test returns document 1, while test Elasticsearch returns no hits.

GET /demo_search/_search
{"query":{"match_phrase":{"text":{"query":"Elasticsearch test"}}}}

2. Term queries

term performs exact matching and should normally target a non-analyzed keyword field.

GET /demo_search/_search
{"query":{"term":{"text.keyword":"This is Elasticsearch test."}}}

Searching text.keyword for only Elasticsearch returns no hit because the complete value differs. A term query containing the full sentence against the analyzed text field also fails because that field was split into tokens.

Use terms to match any of several exact values:

GET /demo_search/_search
{"query":{"terms":{"text.keyword":[
  "This is Elasticsearch test.", "This is a pen."
]}}}

This returns documents 1 and 3.

3. Range queries

Create date samples, assuming the date mapping is already configured:

POST /_bulk
{ "index": { "_index": "test_range", "_id": "1" }}
{ "date": "2000/01/01 09:00:00+0900" }
{ "index": { "_index": "test_range", "_id": "2" }}
{ "date": "2010/08/01 09:00:00+0900" }
{ "index": { "_index": "test_range", "_id": "3" }}
{ "date": "2020/11/01 09:00:00+0900" }
GET /test_range/_search
{"query":{"range":{"date":{
  "gte":"2010/01/01 09:00:00+0900",
  "lte":"2030/01/01 09:00:00+0900"
}}}}

Documents 2 and 3 fall within the inclusive range.

4. Bool queries

bool combines match, term, and range conditions.

POST /_bulk
{ "index": { "_index": "demo_bool", "_id": "1" }}
{ "text": "This is Elasticsearch test.", "id": 1 }
{ "index": { "_index": "demo_bool", "_id": "2" }}
{ "text": "Elasticsearch is God.", "id": 2 }
{ "index": { "_index": "demo_bool", "_id": "3" }}
{ "text": "This is a pen.", "id": 3 }

must, should, and must_not

must is AND, should is OR, and must_not excludes matching documents.

GET /demo_bool/_search
{"query":{"bool":{"must":[
  {"match":{"text":"Elasticsearch"}},
  {"range":{"id":{"lte":1}}}
]}}}

The must version returns document 1. Replacing must with should returns documents 1 and 2; replacing it with must_not returns document 3 with score 0.

filter

filter restricts candidates without affecting relevance scoring.

GET /demo_bool/_search
{"query":{"bool":{
  "must":[{"match":{"text":"Elasticsearch"}}],
  "filter":[{"range":{"id":{"lte":1}}}]
}}}

The filter first limits IDs to 1 or less, and the match condition then returns document 1.

Sort results

GET /demo_bool/_search
{"sort":[{"id":{"order":"desc"}}]}

Documents are returned in ID order 3, 2, 1.

Summary

  • match_all returns every document in an index.
  • match searches analyzed text; multi_match searches multiple fields.
  • match_phrase also preserves term order.
  • term searches exact, non-analyzed values; terms accepts several values.
  • range supports bounds such as gte and lte.
  • bool combines must, should, must_not, and filter.
  • size limits result count, from selects an offset, sort orders results, _source chooses returned fields, and aggs calculates grouped statistics.