[AI Readability Summary]
Elasticsearch works best when you combine full-text search with structured filtering inside a bool query. This pattern solves two common problems at once: results that are searchable but imprecise, and results that are precise but not searchable. Keywords: Elasticsearch, full-text search, structured filtering.
Technical Specification Snapshot
| Parameter | Description |
|---|---|
| Core Technology | Elasticsearch Query DSL |
| Query Language | JSON DSL |
| Communication Protocol | HTTP/REST |
| Typical Field Types | text, keyword, integer, date, boolean |
| Core Queries | match, term, terms, range, bool |
| GitHub Stars | Not provided in the source |
| Core Dependencies | Lucene, inverted index, BM25 |
The standard Elasticsearch query model combines full-text search with structured filtering.
In real-world applications, search rarely depends on a single condition. Users enter keywords and then add constraints such as brand, price, status, or time range. If you use only match, results may feel relevant but remain hard to control. If you use only term or range, results may be precise but lack a real search experience.
That is why the most common Elasticsearch pattern is this: use must for full-text search and filter for structured filtering. This combination balances recall, relevance, and performance, making it the default approach for e-commerce, logging systems, and content platforms.
Full-text search is ideal for natural language content.
match analyzes input text and then calculates relevance scores based on the inverted index and BM25. It is best suited for text fields such as titles, body content, descriptions, and message payloads.
{
"query": {
"match": {
"title": "手机"
}
}
}
This example shows the most basic form of full-text search, which performs analyzed matching on the title field.
Structured queries are ideal for exact values and range conditions.
Structured fields do not require text analysis. They focus on exact matching or range evaluation. Typical fields include brand, status, ID, price, date, city, and boolean values. Their corresponding types are usually keyword, integer, date, and boolean.
{
"query": {
"bool": {
"filter": [
{ "term": { "brand": "华为" } },
{ "range": { "price": { "gte": 1000, "lte": 3000 } } },
{ "term": { "status": 1 } }
]
}
}
}
This example demonstrates three common forms of structured filtering: exact match, range filtering, and status filtering.
The bool query is the core container that connects full-text search and structured filtering.
The real value of a bool query is not just that it can combine conditions, but that it combines them by responsibility. Conditions in must participate in scoring, which makes them suitable for keyword search. Conditions in filter do not participate in scoring and can be cached, which makes them a better fit for high-frequency filtering conditions.
This means that if you place conditions such as brand, inventory, or time range inside must, Elasticsearch will perform meaningless scoring calculations. That wastes CPU and slows down the query.
{
"query": {
"bool": {
"must": [
{ "match": { "title": "手机" } }
],
"filter": [
{ "term": { "brand": "华为" } },
{ "range": { "price": { "gte": 1000, "lte": 3000 } } },
{ "term": { "status": 1 } }
]
}
}
}
This example presents the most standard and recommended query structure in Elasticsearch.
E-commerce search best demonstrates the separation of concerns between must and filter.
Assume the requirement is to search for products whose title contains “electric scooter,” restrict brands to Yadea or Aima, limit price to between 1000 and 5000, require active listing status, and ensure inventory is greater than 0. This scenario combines full-text search, multi-value filtering, numeric ranges, and business-state constraints.
GET /goods/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "电动车"
}
}
],
"filter": [
{
"terms": {
"brand": ["雅迪", "爱玛"]
}
},
{
"range": {
"price": {
"gte": 1000,
"lte": 5000
}
}
},
{
"term": {
"status": 1
}
},
{
"range": {
"stock": {
"gt": 0
}
}
}
]
}
}
}
This query implements a typical product search flow: first recall candidates by keyword, then narrow them precisely with business constraints.
Log search relies on the same query structure.
In log platforms, developers often search for exception keywords while constraining log level, service name, and time window. For example, you may search for NullPointerException in message, while requiring level=ERROR, serviceName=order-service, and a range limited to the last hour.
GET /logs-*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": "NullPointerException"
}
}
],
"filter": [
{ "term": { "level": "ERROR" } },
{ "term": { "serviceName": "order-service" } },
{ "range": { "timestamp": { "gte": "now-1h" } } }
]
}
}
}
This example reflects a high-frequency pattern in log platforms: exception text search combined with tag-based filtering.
Mapping design must explicitly support both full-text and exact-match semantics.
If a field must support full-text search as well as sorting, aggregation, or exact matching, use multi-fields. The most common design is to define the main field as text and a subfield as keyword.
{
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
This mapping allows title to support both full-text search and exact matching.
Common mistakes usually come from semantic modeling, not syntax.
First, placing structured conditions in must. The query runs, but performance suffers.
Second, using a text field for exact filtering. After analysis, matching becomes distorted.
Third, not using bool for composition. As a result, the query cannot express real business requirements.
Fourth, confusing the responsibilities of match and term. That makes query semantics unstable.
AI Visual Insight: This diagram illustrates the Elasticsearch query flow as a pipeline. It starts with user-entered keywords, splits into full-text retrieval and structured conditions, and then converges in a bool query. The technical focus is the separation of responsibilities between must and filter: must handles recall and scoring, while filter handles cache-friendly exact filtering, ultimately producing highly relevant and highly precise results.
The production default is simple: put full-text conditions in must and filters in filter.
You can reduce the Elasticsearch query model to one rule of thumb: put keyword search in must, and put exact-match or range conditions in filter; use text for full-text retrieval, and use keyword for exact filtering; unify complex business logic under a bool query.
When you design fields and DSL around this model, query results become more accurate and execution performance becomes more stable.
FAQ
FAQ 1: Why should fields such as brand and status not go into must?
Because must participates in relevance scoring, while fields such as brand and status usually do not need scoring. Putting them in filter avoids unnecessary computation and improves query performance through caching.
FAQ 2: When should you use text, and when should you use keyword?
Use text when you need analyzed search, such as titles, content, and log messages. Use keyword when you need exact matching, sorting, or aggregation, such as brand, status, city, and tags.
FAQ 3: How should you model a field that needs both search and exact filtering?
Use multi-fields. Define the primary field as text for full-text search, then add a .keyword subfield for exact matching, sorting, and aggregation. This is the safest production practice.
Core Summary: This article systematically reconstructs the Elasticsearch advanced query model, focusing on practical combinations of match, term, range, terms, and bool. It explains why must is responsible for relevance while filter is responsible for high-performance filtering, and it provides DSL examples, mapping design guidance, and common pitfalls for both e-commerce and log-search scenarios.