Elasticsearch是基于Lucene构建的分布式搜索引擎,在日志分析、商品搜索、文档检索等场景中广泛应用。与关系型数据库的LIKE模糊查询不同,Elasticsearch通过倒排索引和分词器实现毫秒级全文检索。正确配置分词器、编写精确的查询DSL、优化索引映射,是Elasticsearch实战中的核心能力。
索引映射与分析器配置
索引映射(Mapping)定义字段类型和分析器,相当于数据库的表结构。创建索引时指定映射:
PUT /articles
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "ik_max_word",
"filter": ["lowercase", "my_stop"]
}
},
"filter": {
"my_stop": {
"type": "stop",
"stopwords": ["的", "了", "是", "在", "和"]
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"fields": {
"keyword": { "type": "keyword", "ignore_above": 256 }
}
},
"content": {
"type": "text",
"analyzer": "my_analyzer"
},
"tags": {
"type": "keyword"
},
"publish_date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
},
"view_count": {
"type": "integer"
},
"url": {
"type": "keyword",
"index": false
}
}
}
}
title字段使用ik_max_word做索引分词(最细粒度切分,召回率高),ik_smart做搜索分词(智能切分,精确度高)。这种”索引粗搜索精”的组合是中文搜索的最佳实践。fields.keyword为title创建keyword子字段,支持精确匹配和聚合排序。index: false使url字段不建索引,仅存储不检索。
中文分词器IK Analyzer安装与测试
Elasticsearch默认分词器对中文按字切分(standard analyzer),无法识别词组。IK Analyzer是中文分词插件,需要安装:
# 在每个节点上安装IK插件
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.12.0/elasticsearch-analysis-ik-8.12.0.zip
# 重启节点
systemctl restart elasticsearch
# 测试分词效果
POST /_analyze
{
"analyzer": "ik_max_word",
"text": "人工智能大模型应用开发实战"
}
# 返回
{
"tokens": [
{"token": "人工智能", "start_offset": 0, "end_offset": 4},
{"token": "大模型", "start_offset": 4, "end_offset": 7},
{"token": "应用", "start_offset": 7, "end_offset": 9},
{"token": "开发", "start_offset": 9, "end_offset": 11},
{"token": "实战", "start_offset": 11, "end_offset": 13}
]
}
IK支持自定义词典扩展。创建扩展词文件config/analysis-ik/extra.dic,每行一个词:
大语言模型
向量数据库
提示工程
在IK配置文件IKAnalyzer.cfg.xml中引用扩展词典:
<properties>
<entry key="ext_dict">extra.dic</entry>
<entry key="ext_stopwords">stopword.dic</entry>
</properties>
修改词典后无需重启Elasticsearch,IK支持热更新——通过定时检测词典文件的修改时间,自动重新加载词典。
布尔查询与多字段搜索
布尔查询(Bool Query)是Elasticsearch最常用的查询类型,通过must、should、must_not、filter组合条件:
POST /articles/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "Kubernetes 部署",
"fields": ["title^3", "content"],
"type": "best_fields",
"tie_breaker": 0.3
}
}
],
"filter": [
{ "term": { "tags": "kubernetes" } },
{
"range": {
"publish_date": {
"gte": "2026-01-01",
"lte": "2026-12-31"
}
}
}
],
"should": [
{ "term": { "tags": "devops" } }
],
"must_not": [
{ "term": { "tags": "draft" } }
]
}
},
"sort": [
{ "_score": { "order": "desc" } },
{ "publish_date": { "order": "desc" } }
],
"from": 0,
"size": 20,
"highlight": {
"fields": {
"title": { "pre_tags": ["<em>"], "post_tags": ["</em>"], "number_of_fragments": 0 },
"content": { "fragment_size": 150, "number_of_fragments": 3 }
}
}
}
multi_match的best_fields策略取匹配度最高字段的分数,title^3将title字段权重提升3倍。tie_breaker=0.3在多个字段都有匹配时,将次要字段分数的30%计入总分。filter不参与评分且结果会被缓存,适合精确过滤条件。should在有must条件时仅影响排序,无must条件时至少需匹配一个should。
高亮(highlight)在搜索结果中标记匹配的关键词。number_of_fragments: 0表示返回完整字段内容而非片段。
聚合查询与分面统计
聚合(Aggregation)类似SQL的GROUP BY,用于统计分析和分面搜索:
POST /articles/_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{ "range": { "publish_date": { "gte": "2026-01-01" } } }
]
}
},
"aggs": {
"tags_stats": {
"terms": {
"field": "tags",
"size": 20,
"order": { "_count": "desc" }
},
"aggs": {
"avg_views": { "avg": { "field": "view_count" } },
"date_histogram": {
"date_histogram": {
"field": "publish_date",
"calendar_interval": "month",
"format": "yyyy-MM"
}
}
}
},
"monthly_count": {
"date_histogram": {
"field": "publish_date",
"calendar_interval": "month",
"format": "yyyy-MM",
"min_doc_count": 0
}
}
}
}
size: 0不返回文档,仅返回聚合结果。嵌套聚合在tags_stats下先按标签分组,每组再计算平均浏览量和按月发布量。min_doc_count: 0确保没有文档的月份也返回0值,避免时间序列断点。
索引性能调优与刷新策略
Elasticsearch的准实时性依赖于refresh操作——将内存缓冲区的数据写入Segment使其可搜索。默认每1秒refresh一次。批量写入时可以临时关闭refresh:
# 批量写入前关闭refresh
PUT /articles/_settings
{ "index.refresh_interval": "-1" }
# 批量写入
POST /_bulk
{ "index": { "_index": "articles" } }
{ "title": "...", "content": "..." }
{ "index": { "_index": "articles" } }
{ "title": "...", "content": "..." }
# 批量写入后恢复并手动刷新
PUT /articles/_settings
{ "index.refresh_interval": "1s" }
POST /articles/_refresh
关闭refresh期间写入的文档不可搜索,但写入吞吐量可提升3-5倍。适合离线数据导入场景。
Bulk API的批量大小建议5-15MB,每批1000-5000条文档。过大的批次会占用过多JVM堆内存,可能触发GC停顿。监控Bulk请求的响应时间,超过30秒说明批次过大:
# 查看索引统计
GET /articles/_stats/indexing
# 关键指标
# index_total: 总索引操作数
# index_current: 当前并发索引操作数
# index_time_in_millis: 总索引耗时
# throttled_time_in_millis: 因限流等待时间
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/elasticsearch-quan-wen-jian-suo-shi-zhan-fen-ci-qi-pei-zhi/