Elasticsearch Basic Search Queries

Searching is Elasticsearch's core skill. This topic covers the most-used query types — from returning every document to finding exact values and ranges.

How a Search Request Works

You send:
  GET /products/_search  +  query JSON

Elasticsearch:
  1. Reads the inverted index
  2. Finds matching document IDs
  3. Scores each match by relevance
  4. Returns top N documents

You receive:
  { "hits": { "total": {...}, "hits": [ ... ] } }

The Search Response Structure

{
  "took": 5,           <-- milliseconds to run
  "hits": {
    "total": {
      "value": 42      <-- total matching documents
    },
    "hits": [          <-- actual documents (first 10 by default)
      {
        "_index": "products",
        "_id": "101",
        "_score": 1.8,  <-- relevance score (higher = better match)
        "_source": { ... }
      }
    ]
  }
}

Query 1: match_all

Returns every document in the index. Useful for testing and exploring data.

GET /products/_search
{
  "query": {
    "match_all": {}
  }
}

Query 2: match

The standard full-text search query. It analyzes your search text and finds documents where the field contains those words.

GET /products/_search
{
  "query": {
    "match": {
      "name": "wireless keyboard"
    }
  }
}

This finds documents where the name field contains "wireless" OR "keyboard." Documents with both words score higher.

Query 3: term

Finds documents where a field contains an exact value. Use this on keyword, number, boolean, and date fields — never on text fields.

GET /products/_search
{
  "query": {
    "term": {
      "category": "electronics"
    }
  }
}

If you use term on a text field, it often returns nothing because the text field is analyzed (lowercased, split into tokens) but term looks for the exact unmodified value.

match vs term — At a Glance

Query: "Wireless Keyboard"

match on text field:
  Elasticsearch analyzes: ["wireless", "keyboard"]
  Finds any document containing either word
  ✔ Returns "Best Wireless Keyboard" and "Gaming Keyboard"

term on keyword field:
  Looks for exactly "Wireless Keyboard"
  ✔ Returns only docs with that exact string
  ✘ "wireless keyboard" (lowercase) would NOT match

Query 4: terms

Matches documents where a field contains any one of a list of values — like SQL's IN clause.

GET /products/_search
{
  "query": {
    "terms": {
      "category": ["electronics", "accessories", "gadgets"]
    }
  }
}

Query 5: range

Finds documents where a numeric or date field falls within a range.

GET /products/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 500,
        "lte": 2000
      }
    }
  }
}
OperatorMeaning
gteGreater than or equal to
gtGreater than
lteLess than or equal to
ltLess than

Date ranges work the same way:

"range": {
  "created_at": {
    "gte": "2024-01-01",
    "lte": "2024-12-31"
  }
}

Query 6: exists

Finds documents where a specific field has any value (is not null and not missing).

GET /products/_search
{
  "query": {
    "exists": {
      "field": "discount_price"
    }
  }
}

Controlling Result Count and Pagination

By default, search returns 10 documents. Use size and from to control pagination.

GET /products/_search
{
  "query": { "match_all": {} },
  "size": 20,
  "from": 40
}

This returns documents 41 through 60 — page 3 of a 20-per-page result set.

Sorting Results

GET /products/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "price": "asc" },
    { "name.raw": "asc" }
  ]
}

Sort by price ascending, then by name alphabetically as a tiebreaker. Note that sorting by name requires the keyword sub-field (name.raw), not the analyzed text field.

Returning Only Specific Fields

GET /products/_search
{
  "query": { "match_all": {} },
  "_source": ["name", "price", "category"]
}

Elasticsearch returns only those three fields instead of the full document, which reduces network overhead on large documents.

Leave a Comment