3. Queries & Filtering
Duration45min AI Banned
Introduction
Now that you understand the Elastic Stack architecture and document structure, it’s time to master querying and filtering data. In this workshop, you’ll learn how to precisely search for documents, filter results, and understand the critical difference between text and keyword fields.
By the end of this session, you’ll be able to write production-ready queries that efficiently retrieve exactly the data you need.
Learning Objectives
By completing this workshop, you will be able to:
- ✅ Query documents using Elasticsearch Query DSL (term, range, bool queries)
- ✅ Filter and sort results using source filtering, sorting, and pagination
- ✅ Understand the difference between text and keyword field types
- ✅ Apply the correct query type for different use cases
Understanding Elasticsearch Queries
Before diving into exercises, let’s understand how Elasticsearch queries work. An Elasticsearch query is composed of several optional sections that control which data is returned and how it’s presented.
Query Anatomy
Here’s the general structure with all parameters used in this workshop:
|
|
Understanding Boolean Query Clauses:
The bool query has four types of clauses, each with different behavior:
-
must: Documents MUST match these conditions (AND logic). Contributes to relevance score. Use for conditions that are required AND where scoring matters. -
should: At least one condition SHOULD match (OR logic). Contributes to relevance score. Documents matching moreshouldclauses rank higher. If nomustorfilterexists, at least oneshouldmust match. Ifmustorfilterexists,shouldclauses are optional but boost score. -
filter: Documents MUST match these conditions (AND logic). Does NOT contribute to score. Faster thanmustbecause results are cached. Use for exact filters like ranges, statuses, or IDs where scoring doesn’t matter. -
must_not: Documents MUST NOT match these conditions (exclusion). Does NOT contribute to score. Use to exclude unwanted documents.
Other Key Concepts:
-
_sourcefiltering: Controls which fields are returned in results. Use["field1", "field2"]to return specific fields, orfalseto exclude all source data. -
fromandsize(pagination):fromspecifies how many results to skip from the beginning of the result set (sorted by relevance or yoursortclause).sizespecifies how many results to return. Example:from: 20, size: 10returns results 21-30. -
termvsmatch:termqueries perform exact matching (use for IDs, statuses, exact values).matchqueries perform full-text search with analysis (use for searching text content).
Response Anatomy
Every Elasticsearch search response has this structure:
|
|
Important fields:
took: Query execution time - useful for performance monitoringhits.total.value: Total matching documents - may be limited to 10,000 by defaulthits.hits[]: Actual documents returned (limited bysizeparameter)_score: Relevance score -nullwhen usingsortorfiltercontext
For detailed documentation on all query types, search modifiers, aggregations, and query contexts, refer to the Elasticsearch Documentation page.
Section 1: Basic Search Queries
Now let’s practice filtering transactions based on specific criteria. We’ll learn each query type and immediately apply it.
Exercise 1.1: Term Query - Exact Matching
Use term queries for exact matching on keyword fields (statuses, IDs, categories):
|
|
Important: Use the .keyword subfield for exact matching on text fields. The text field without .keyword is analyzed (tokenized, lowercased), while .keyword preserves the exact value.
Query
Write a query to find all transactions where the order status is “confirmed”.
Exercise 1.2: Range Query - Numeric and Date Ranges
Use range queries for numeric values or date ranges:
|
|
Available operators: gte (≥), lte (≤), gt (>), lt (<)
Query
Write a query to find all transactions where the total amount is greater than 200€.
Exercise 1.3: Date Math - Time-Based Queries
For time-based queries, use date math expressions with range queries:
|
|
Common expressions:
"now-1h"- last hour"now-1d"- last day"now-7d"- last 7 days"now-7d/d"- last 7 days rounded to day
Query
Write a query to find all transactions created in the last hour.
Exercise 1.4: Boolean Query - Combining Conditions
Use bool queries to combine multiple conditions:
|
|
The must clause ensures ALL conditions match (AND logic). Refer to the Query Anatomy section for other clause types (should, filter, must_not).
Query
Write a query to find all transactions that are confirmed AND have a total amount greater than 200€.
Section 2: Understanding Text vs Keyword
Now that you’ve written several queries using .keyword, let’s understand WHY this is necessary. This is one of the most important concepts in Elasticsearch.
Concepts: Text vs Keyword Field Types
Elasticsearch provides two main string field types with fundamentally different behaviors:
Text Fields (text type):
- Purpose: Full-text search (finding documents that contain certain words or phrases)
- Analysis process: Text is tokenized, lowercased, and stemmed before indexing
- Example: “Wireless Bluetooth Headphones” → tokens:
["wireless", "bluetooth", "headphones"]
- Example: “Wireless Bluetooth Headphones” → tokens:
- Query behavior: Search terms are also analyzed, so “bluetooth” matches “Bluetooth”
- Use cases: Article content, product descriptions, user comments, any searchable text
- Limitations: Cannot be used for exact matching, sorting, or aggregations
Keyword Fields (keyword type):
- Purpose: Exact matching, filtering, sorting, and aggregations
- Analysis process: No analysis—the entire string is stored as-is
- Example: “Wireless Bluetooth Headphones” → stored exactly as
"Wireless Bluetooth Headphones"
- Example: “Wireless Bluetooth Headphones” → stored exactly as
- Query behavior: Must match exactly (case-sensitive)
- Use cases: IDs, email addresses, statuses, categories, tags, country codes
- Limitations: Not suitable for full-text search of long text
The Multi-Field Pattern (.keyword subfield):
Dynamic mapping often creates both types for string fields:
|
|
This allows flexibility but consumes more storage (data is indexed twice).
Exercise 2.1: Testing Text vs Keyword Behavior
Test the difference between text and keyword behavior by running these three queries on the transactions-* index:
Queries
Run these three queries and observe the differences:
- Query A: Use
matchquery on thetextfield (search for “bluetooth” in product names) - Query B: Use
termquery on thetextfield (try exact term matching on analyzed field) - Query C: Use
termquery on the.keywordsubfield (exact match on keyword field)
Query A: Using match on text field
|
|
Query B: Using term on text field
|
|
Query C: Using term on keyword subfield
|
|
Resources
To understand the behavior of these queries, refer to the Elasticsearch Documentation page or read this tutorial: Match Query vs Term Query in Elasticsearch.
Questions
- Why does Query A return results but Query B doesn’t, even though they search for the same word
"Bluetooth"? - When would you use
matchqueries vstermqueries? - What happens if you search for
"BLUETOOTH"(all uppercase) with Query A vs Query C? - Why can’t you use text fields for sorting or aggregations?