Elasticsearch DSL 核心语法大全:match、bool、range、聚合查询实战解析
DSL,全称为Domain Specific Language,即领域特定语言,是一种旨在特定领域内高效解决具体问题的编程或查询语言。与通用编程语言(如Java、Python等)相比,DSL专注于一个特定的应用领域,提供了针对该领域的更精确和高效的抽象。
在Elasticsearch中,DSL指的是Elasticsearch提供的基于JSON格式的完整查询语言,被称为Query DSL。这种语言使用户能够定义复杂的搜索查询,并支持多种类型的查询子句,包括但不限于全文搜索、结构化查询、聚合分析等。通过使用Query DSL,用户可以灵活地构建查询条件,控制结果排序,进行分页处理,甚至执行复杂的统计分析任务。例如,你可以使用它来执行简单的关键词匹配查询,也可以构建复杂的布尔查询来组合多个查询条件。这使得Elasticsearch不仅是一个强大的搜索引擎,也是一个灵活的数据分析工具。
一、准备测试数据
在深入学习 DSL 之前,我们需要先创建一个索引并填充一些测试数据。
1. 创建商品索引 (products
)
PUT http://192.168.130.61:9200/products
{"settings": {"number_of_shards": 1,"number_of_replicas": 0},"mappings": {"properties": {"item": { "type": "keyword" },"title": { "type": "text" },"price": { "type": "float" },"group": { "type": "integer" },"brand": { "type": "keyword" },"hobby": { "type": "text" },"created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }}}
}
2. 批量写入测试数据
POST http://192.168.130.61:9200/_bulk
{ "index": { "_index": "products" } }
{ "item": "PROD-001", "title": "复古风格木质书桌", "price": 899.00, "group": 1, "brand": "家逸", "hobby": "阅读", "created_at": "2025-07-01 10:00:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-002", "title": "人体工学电脑椅", "price": 1299.50, "group": 1, "brand": "舒适达", "hobby": "办公", "created_at": "2025-07-02 11:30:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-003", "title": "智能恒温保温杯", "price": 158.00, "group": 2, "brand": "智饮", "hobby": "品茶", "created_at": "2025-07-03 14:20:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-004", "title": "无线蓝牙降噪耳机", "price": 699.00, "group": 2, "brand": "声悦", "hobby": "听音乐", "created_at": "2025-07-04 16:45:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-005", "title": "专业电竞游戏鼠标", "price": 299.99, "group": 3, "brand": "极光", "hobby": "游戏", "created_at": "2025-07-05 09:15:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-006", "title": "高清便携投影仪", "price": 2199.00, "group": 3, "brand": "视界", "hobby": "观影", "created_at": "2025-07-06 13:50:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-007", "title": "多功能厨房料理机", "price": 118.00, "group": 4, "brand": "厨乐", "hobby": "烹饪", "created_at": "2025-07-07 18:30:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-008", "title": "天然有机棉四件套", "price": 399.00, "group": 5, "brand": "安睡", "hobby": "睡眠", "created_at": "2025-07-08 20:10:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-009", "title": "户外折叠野营帐篷", "price": 599.00, "group": 6, "brand": "探路者", "hobby": "露营", "created_at": "2025-07-09 08:00:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-010", "title": "儿童益智积木玩具", "price": 89.90, "group": 7, "brand": "乐智", "created_at": "2025-07-10 15:25:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-011", "title": "静音加湿器", "price": 188.00, "group": 5, "brand": "润物", "created_at": "2025-07-11 12:00:00" }
{ "index": { "_index": "products" } }
{ "item": "PROD-012", "title": "复古金属台灯", "price": 256.00, "group": 1, "brand": "光影", "hobby": "阅读", "created_at": "2025-07-12 17:40:00" }
说明:所有数据均为虚构,不涉及任何真实用户或商业信息。
二、什么是 DSL?
Elasticsearch 提供了基于 JSON 的完整 Query DSL(Domain Specific Language,领域特定语言) 来定义查询。DSL 使得构建复杂查询变得灵活且强大。它分为两种主要类型:
- 叶查询子句 (Leaf query clauses):针对特定字段搜索特定值,如
match
,term
,range
。 - 复合查询子句 (Compound query clauses):组合多个查询子句,如
bool
查询。
三、核心 DSL 查询案例
3.1 全文检索 - match
查询
对文本字段进行分词搜索,找到包含任意一个分词的文档。
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"title": "书桌 椅子"}}
}
结果:会返回标题中包含“书桌”或“椅子”(或“椅子”相关分词)的文档,如
PROD-001
和PROD-002
。
3.2 完全匹配 - match_phrase
查询
要求查询词项必须作为一个整体短语出现,顺序和距离都需匹配。
POST http://192.168.130.61:9200/products/_search
{"query": {"match_phrase": {"title": "人体工学"}}
}
结果:只返回标题中精确包含“人体工学”这个短语的文档,如
PROD-002
。
3.3 全量查询 - match_all
返回索引中的所有文档。
POST http://192.168.130.61:9200/products/_search
{"query": {"match_all": {}}
}
提示:直接发送
GET http://192.168.130.61:9200/products/_search
不带请求体,默认行为等同于match_all
。
3.4 分页查询 - size
和 from
控制返回结果的数量和起始位置。
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"group": 1}},"size": 3,"from": 0
}
参数说明:
size
: 每页显示条数,默认 10。from
: 跳过的文档数(偏移量),默认 0。- 计算公式:第 N 页的
from
=(N-1) * size
。温馨提示:避免深度分页(如
from
非常大),性能会急剧下降。生产环境建议使用 Search After 或 Scroll API。
3.5 指定返回字段 - _source
只返回 _source
中的指定字段,减少网络传输量。
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"group": 1}},"size": 5,"from": 0,"_source": ["item", "title", "price", "group"]
}
结果:返回的文档只包含
item
,title
,price
,group
这四个字段。
3.6 查询存在字段的文档 - exists
查找包含指定字段(且字段值不为 null
)的文档。
POST http://192.168.130.61:9200/products/_search
{"query": {"exists": {"field": "hobby"}}
}
结果:返回
hobby
字段有值的文档,如PROD-001
,PROD-002
等。
3.7 语法高亮 - highlight
在返回结果中对匹配的文本进行高亮标记。
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"title": "椅子"}},"highlight": {"pre_tags": ["<span style='color:red; font-weight:bold;'>"],"post_tags": ["</span>"],"fields": {"title": {}}}
}
结果:在
title
字段中,“椅子”一词会被包裹在红色加粗的<span>
标签内。
3.8 基于字段排序 - sort
对查询结果按指定字段进行排序。
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"group": 1}},"sort": [{"price": {"order": "desc"}}]
}
结果:
group
为 1 的商品按price
降序排列(从高到低)。
3.9 多条件查询 - bool
组合多个查询条件,是构建复杂查询的核心。
9.1 must
(必须满足)
所有 must
子句都必须匹配。
POST http://192.168.130.61:9200/products/_search
{"query": {"bool": {"must": [{"match_phrase": {"title": "保温杯"}},{"term": {"price": 158}}]}}
}
结果:返回标题包含“保温杯”且价格等于 158 的文档,即
PROD-003
。
9.2 must_not
(必须不满足)
所有 must_not
子句都不能匹配。
POST http://192.168.130.61:9200/products/_search
{"query": {"bool": {"must_not": [{"match": {"group": 7}},{"match_phrase": {"title": "儿童"}}]}}
}
结果:返回
group
不是 7 且标题不包含“儿童”的文档。
9.3 should
(满足其一)
满足一个或多个 should
子句。可通过 minimum_should_match
控制最少匹配数量。
POST http://192.168.130.61:9200/products/_search
{"query": {"bool": {"should": [{ "match": { "group": 3 } },{ "match_phrase": { "title": "投影仪" } },{ "match": { "price": 299.99 } }],"minimum_should_match": 2}},"sort": [{ "price": { "order": "desc" } }]
}
结果:返回至少满足上述三个条件中两个的文档,并按价格降序排列。
3.10 精确匹配多个值 - terms
查找字段值在指定列表中的文档。
POST http://192.168.130.61:9200/products/_search
{"query": {"terms": {"price": [158, 118, 188]}}
}
结果:返回价格为 158、118 或 188 的文档,如
PROD-003
,PROD-007
,PROD-011
。
3.11 范围查询 - range
查找字段值在指定范围内的文档。
POST http://192.168.130.61:9200/products/_search
{"query": {"bool": {"must": [{ "match_phrase": { "group": 5 } }],"filter": {"range": {"price": {"gte": 300,"lte": 500}}}}}
}
结果:返回
group
为 5 且价格在 300 到 500 之间的文档,即PROD-008
。参数说明:
gt
: 大于lt
: 小于gte
: 大于等于lte
: 小于等于注意:
filter
子句不参与相关性评分计算,通常比must
更高效。
3.12 多词搜索(operator
)
控制 match
查询中多个词项的逻辑关系。
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"title": {"query": "智能 保温","operator": "and"}}},"highlight": {"pre_tags": ["<em>"],"post_tags": ["</em>"],"fields": {"title": {}}}
}
结果:只有当
title
同时包含“智能”和“保温”时才匹配,如PROD-003
。默认operator
为or
。
3.13 权重提升 - boost
为特定查询条件赋予更高的权重,影响文档的相关性得分。
POST http://192.168.130.61:9200/products/_search
{"query": {"bool": {"must": [{ "match": { "group": 1 } }],"should": [{"match_phrase": {"title": {"query": "书桌","boost": 10}}},{"match_phrase": {"title": {"query": "椅子","boost": 5}}}]}},"highlight": {"fields": {"title": {}}}
}
结果:在
group
为 1 的商品中,包含“书桌”的文档得分会远高于仅包含“椅子”的文档,因此PROD-001
会排在PROD-002
前面。
四、聚合查询(Aggregations)
用于对数据进行统计分析,不返回原始文档。
4.1 统计每个组的商品数量
POST http://192.168.130.61:9200/products/_search
{"aggs": {"product_count_by_group": {"terms": {"field": "group"}}},"size": 0
}
结果:返回每个
group
值对应的商品数量统计。
4.2 查找 6 组商品中最贵的
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"group": 6}},"aggs": {"max_price_in_group_6": {"max": {"field": "price"}}},"size": 0
}
结果:返回
group
为 6 的商品中的最高价格。
4.3 查找 1 组商品中最便宜的
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"group": 1}},"aggs": {"min_price_in_group_1": {"min": {"field": "price"}}},"size": 0
}
结果:返回
group
为 1 的商品中的最低价格。
4.4 计算 5 组商品的平均价格
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"group": 5}},"aggs": {"avg_price_in_group_5": {"avg": {"field": "price"}}},"size": 0
}
结果:返回
group
为 5 的商品的平均价格。
4.5 计算购买 5 组所有商品的总价格
POST http://192.168.130.61:9200/products/_search
{"query": {"match": {"group": 5}},"aggs": {"total_cost_group_5": {"sum": {"field": "price"}}},"size": 0
}
结果:返回
group
为 5 的所有商品价格之和。
五、推荐阅读
- 官方 Query DSL 文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
- 官方聚合文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html