Elasticsearch 的查询语言非常强大,核心是基于 JSON 的 Query DSL (Domain Specific Language),您可以通过发送 HTTP 请求(通常是 GET 或 POST)到 _search API 来执行查询。

基础查询结构
任何查询请求的基本结构都如下所示:
GET /your_index_name/_search
{
"query": {
"your_query_type": {
"your_query_parameters": "your_query_value"
}
},
"_source": ["field1", "field2"], // 可选:指定返回哪些字段
"from": 0, // 可选:分页起始位置
"size": 10, // 可选:返回文档数量
"sort": [ // 可选:排序
{
"field_name": {
"order": "asc" // 或 "desc"
}
}
]
}
GET /your_index/_search:对your_index索引进行搜索,可以使用_all或 搜索所有索引,但不推荐。query:查询子句,定义了查询的核心逻辑。_source:返回结果中只包含指定的字段,可以减少网络传输,提高性能。from和size:用于分页。from是起始文档的偏移量,size是要获取的文档数量,默认from=0,size=10。sort:对结果进行排序。
核心查询类型
全文搜索
用于在 text 类型的字段中搜索关键词,会进行分词和相关性评分。
-
match:最常用的全文查询,它会将查询字符串进行分词,然后去匹配文档。GET /your_index/_search { "query": { "match": { "title": "search engine" // 会匹配 "search" 或 "engine" } } } -
match_phrase:短语匹配,要求查询字符串中的所有词都必须按顺序出现在文档中。
(图片来源网络,侵删)GET /your_index/_search { "query": { "match_phrase": { "title": "search engine" // 必须精确匹配 "search engine" 这个短语 } } } -
multi_match:在多个字段中执行match查询。GET /your_index/_search { "query": { "multi_match": { "query": "elasticsearch", "fields": ["title^3", "content"] // 在 title 字段(权重3倍)和 content 字段中搜索 } } }
精确值查询
用于匹配 keyword、数字、布尔值、日期等不进行分词的字段。
-
term:精确匹配单个词。// 查找 status 字段值恰好为 "published" 的文档 GET /your_index/_search { "query": { "term": { "status": "published" } } } -
terms:精确匹配多个词中的任意一个。
(图片来源网络,侵删)// 查找 status 字段值为 "published" 或 "draft" 的文档 GET /your_index/_search { "query": { "terms": { "status": ["published", "draft"] } } } -
range:范围查询,适用于数字、日期。// 查找 age 在 18 到 30 之间的文档(包含18和30) GET /your_index/_search { "query": { "range": { "age": { "gte": 18, // greater than or equal "lte": 30 // less than or equal } } } } // 日期范围查询 GET /your_index/_search { "query": { "range": { "date_field": { "gt": "2025-01-01", // greater than "lt": "2025-01-01" // less than } } } }
布尔查询
bool 查询是构建复杂查询的核心,它通过组合其他查询子句来实现,它包含四个子句:
must:必须匹配,所有子句都必须为true,贡献到相关性评分。filter:必须匹配,所有子句都必须为true,但不贡献到相关性评分,结果会被缓存,性能更高。should:应该匹配,至少有一个子句为true,可以通过minimum_should_match设置最少匹配数量。must_not:必须不匹配,所有子句都必须为false,不贡献评分,结果会被缓存。
GET /your_index/_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "elasticsearch" } }
],
"filter": [
{ "term": { "status": "published" } },
{ "range": { "age": { "gte": 18 } } }
],
"should": [
{ "match": { "tags": "database" } }
],
"must_not": [
{ "term": { "author_id": "123" } }
]
}
}
}
解释包含 "elasticsearch",状态为 "published",年龄大于等于 18,作者ID不为 "123" 的文档,如果还带有 "database" 标签,则相关性评分会更高。
复合查询
bool 查询 (布尔查询)
如上所述,这是最常用的复合查询,用于组合多个查询条件。
function_score 查询
根据一个函数的结果来修改文档的 _score,从而影响相关性排序。
GET /your_index/_search
{
"query": {
"function_score": {
"query": {
"match": { "category": "electronics" }
},
"field_value_factor": {
"field": "sales", // 根据sales字段的值来增加分数
"modifier": "log1p", // 对值进行 log(1+x) 处理,避免过大
"factor": 2.0 // 乘以一个因子
}
}
}
}
效果:在所有匹配 "electronics" 的文档中,sales 值越高的文档,其相关性得分也越高,排名越靠前。
高级查询
aggregations (聚合)
聚合用于对数据进行分组、计算和统计,类似于 SQL 中的 GROUP BY 和 COUNT、SUM 等。
terms:分组聚合。avg、sum、min、max:数值计算聚合。cardinality:基数聚合,计算唯一值的数量。
GET /your_index/_search
{
"size": 0, // 不关心文档内容,只关心聚合结果,所以设置为0
"aggs": {
"group_by_status": { // 聚合名称
"terms": { // 按字段值分组
"field": "status.keyword"
},
"aggs": { // 子聚合
"avg_age": { // 子聚合名称
"avg": { "field": "age" } // 计算每个分组的平均年龄
}
}
},
"unique_authors": { // 另一个聚合
"cardinality": { "field": "author_id" } // 计算作者总数
}
}
}
suggesters (建议)
用于实现搜索框的自动补全功能。
completion:基于completion类型的字段进行建议。term:基于分词结果进行拼写纠错建议。
GET /your_index/_search
{
"suggest": {
"my-suggestion": { // 建议名称
"text": "search en", // 用户输入的文本
"completion": { // 建议类型
"field": "suggest_field", // 建议字段
"size": 5 // 返回5个建议
}
}
}
}
常用操作命令
查看索引信息
# 查看所有索引 GET /_cat/indices?v # 查看特定索引的映射 GET /your_index_name/_mapping # 查看特定索引的设置 GET /your_index_name/_settings
索引数据
POST /your_index_name/_doc/1
{: "Getting Started with Elasticsearch",
"content": "Elasticsearch is a powerful search engine...",
"tags": ["search", "database"],
"publish_date": "2025-10-27"
}
更新数据
POST /your_index_name/_doc/1/_update
{
"doc": {
"tags": ["search", "database", "nosql"]
}
}
删除数据
# 删除文档 DELETE /your_index_name/_doc/1 # 删除整个索引 DELETE /your_index_name
实用技巧
- 使用
GET代替POST:对于查询,GET和POST都可以,但GET更符合 RESTful 规范,且可以被缓存。 - 使用
Kibana Dev Tools:强烈建议在 Kibana 的 Dev Tools 中编写和测试查询,它提供了语法高亮、自动补全和历史记录功能。 - 理解
_source:始终在查询中使用_source字段来指定你需要的字段,这能极大地减少网络开销和提高查询性能。 filtervsmust:当你只关心文档“是否存在”而不关心其“相关性得分”时,使用filter子句,它会利用缓存,速度更快。- 分页陷阱:
from+size的分页方式在深度分页时(from=10000, size=10)性能会很差,因为 ES 需要计算从 0 到 10000 的所有文档,对于深度分页,应考虑使用search_after或scrollAPI。
希望这份指南对您有帮助!Elasticsearch 的查询功能非常丰富,以上只是冰山一角,但涵盖了绝大部分日常使用场景。
