Elasticsearch 全文搜索实战:从索引设计到复杂查询的生产级方案
数据库的 LIKE ‘%keyword%’ 在数据量破百万时基本是废的。全文搜索的解决方案是 Elasticsearch——一个基于 Lucene 的分布式搜索和分析引擎。
倒排索引:为什么 ES 搜得这么快
传统数据库按行存储——搜索需要逐行扫描。ES 的倒排索引按词存储——每个词对应一个文档 ID 列表,查询时直接定位到相关文档,无需全表扫描。
例如搜索 Docker 容器时,ES 直接取交集定位到匹配文档,速度比数据库的 LIKE 快几个数量级。
映射(Mapping)设计
映射定义了文档字段的类型和索引行为。最常见的坑是字符串的两种类型:
| 类型 | 用途 | 示例 |
|---|---|---|
| text | 全文搜索(分词) | 文章内容、描述 |
| keyword | 精确匹配(不分词) | 标签、状态、ID |
title 字段应该同时映射为 text(分词搜索)+ keyword 子字段(用于排序和聚合),这是生产环境的标准做法。
IK 中文分词器
默认分词器对中文只会逐字拆分——容器化部署变成容、器、化、部、署——完全失去语义。IK 分词器解决了这个问题:
ik_max_word 做最细粒度切分:容器化部署 -> 容器化、容器、部署。ik_smart 做粗粒度切分:容器化部署 -> 容器化、部署。
Bool Query:多条件组合查询
Bool Query 是 ES 查询的通用语言,四种子句:
- must:必须匹配(AND + 参与评分)
- filter:必须匹配(AND + 不评分 + 更快)
- must_not:必须不匹配(NOT)
- should:可选匹配(OR + 提升相关性评分)
将评分查询放在 must,精确过滤放在 filter(利用缓存加速),能达到最佳性能。
聚合分析:不仅仅是搜索
ES 的聚合能力相当于一个实时分析引擎——terms 聚合做标签统计、date_histogram 做时间趋势分析、avg/sum 做数值计算。一套查询既能返回搜索结果,又能附带聚合分析数据。
分片策略
单个分片不要超过 50GB。写入密集型场景适当增加分片数以提升并发。搜索密集型场景每个节点上的分片数控制在 20 个以内,避免分片间协调开销。
总结
ES 的本质是分布式文档存储 + 搜索引擎 + 分析引擎的三合一系统。倒排索引是速度的秘密,正确的映射是准确性的基础,IK 分词是中文搜索的必需品,Bool Query 是所有复杂查询的通用语言。掌握了这些,你就拥有了真正的全文搜索能力。
