搜索引擎
搜索引擎用于解决“从大量业务数据中快速找到最相关结果”的问题。商业系统里最常见的不是单纯查一篇内容,而是商品搜索、订单检索、工单检索、日志检索、筛选聚合、搜索建议和附近门店查询。
关系型数据库更擅长事务、主键查询、精确条件和强一致写入;搜索引擎更擅长全文检索、分词、相关性排序、高亮、聚合分析和海量日志查询。二者不是替代关系,而是分工关系。
本目录内容
为什么需要搜索引擎
以电商商品搜索为例,用户通常不会输入完整商品名,而是输入:
text
无线降噪耳机 300以内这个请求背后至少包含几层意图:
无线、降噪、耳机是全文搜索关键词。300以内是价格范围。- 用户可能还想按品牌、销量、是否有货、店铺、发货地筛选。
- 排序不能只按时间,通常要结合相关性、销量、价格、库存、业务权重。
- 页面还需要高亮、分类聚合、品牌聚合、价格区间聚合。
如果只靠数据库 like '%无线降噪耳机%',会遇到这些问题:
| 问题 | 后果 |
|---|---|
前后 %like% 很难利用普通 BTree 索引 | 商品量大后查询变慢 |
| 中文没有天然空格 | “蓝牙耳机”“耳机蓝牙版”命中效果不稳定 |
| 只能做字符串包含 | 无法很好处理同义词、品牌词、型号词 |
| 相关性排序弱 | 命中关键词多、标题更相关的商品不一定排前面 |
| 高亮和摘要需要额外开发 | 用户不知道结果为什么命中 |
| 聚合筛选成本高 | 品牌、分类、价格区间统计会拖慢主库 |
搜索引擎的做法是:写入时先把文本拆成词并建立倒排索引,查询时直接根据词找到候选文档,再做过滤、打分和排序。
搜索流程
mermaid
flowchart TD
A["业务数据<br/>商品、订单、日志"] --> B["字段清洗和反范式组装"]
B --> C["分词和 Mapping 处理"]
C --> D["建立倒排索引"]
E["用户输入关键词和筛选条件"] --> F["查询分词"]
F --> G["匹配倒排索引"]
G --> H["结构化条件过滤"]
H --> I["相关性和业务权重排序"]
I --> J["返回列表、高亮、聚合结果"]这个流程里最重要的是“提前建索引”。ES 查询快不是因为它临时扫数据更快,而是写入时已经把可搜索结构准备好了。
数据库和搜索引擎区别
| 对比项 | 数据库 | 搜索引擎 |
|---|---|---|
| 核心目标 | 事务一致性、结构化存储 | 快速检索、分析、相关性排序 |
| 数据结构 | 表、行、列、BTree 索引 | 文档、字段、倒排索引、列式 doc values |
| 典型查询 | 主键、唯一索引、范围、Join | match、bool、高亮、聚合、地理距离 |
| 写入语义 | 强事务更成熟 | 近实时搜索,写入后受 refresh 影响 |
| 适合场景 | 订单、支付、库存、账户 | 商品搜索、日志分析、工单检索、运营筛选 |
| 不适合场景 | 大规模全文相关性搜索 | 替代事务主库、强一致扣库存 |
商业系统最常见架构是:MySQL 保存事实数据,Elasticsearch 保存面向搜索的冗余视图。如果 ES 数据出错,可以从 MySQL、消息或 Binlog 重新构建。
商业常用场景
| 场景 | 典型需求 | ES 负责什么 |
|---|---|---|
| 商品搜索 | 关键词、品牌、分类、价格、销量、库存、排序 | 全文召回、过滤、排序、聚合筛选、高亮 |
| 订单检索 | 订单号、手机号后四位、买家、状态、时间范围 | 后台多条件快速检索 |
| 工单检索 | 标题、描述、处理人、优先级、状态、SLA | 关键词检索和运营筛选 |
| 日志检索 | traceId、错误码、接口、时间范围 | 海量日志查询、聚合分析 |
| 搜索建议 | 输入几个字出现候选词 | completion、search_as_you_type、ngram |
| 附近门店 | 经纬度、距离、城市、营业状态 | geo_point 和距离排序 |
| 运营分析 | 品牌数量、价格分布、状态统计 | terms、range、date_histogram 聚合 |
学习路线
mermaid
flowchart TD
A["理解为什么不用 like 扛全文搜索"] --> B["学习倒排索引"]
B --> C["学习分词器和同义词"]
C --> D["学习 Mapping 字段设计"]
D --> E["学习 Query DSL"]
E --> F["学习聚合、分页、高亮、排序"]
F --> G["学习分片、副本和集群健康"]
G --> H["落地商业搜索实战"]
H --> I["排查搜索不准、查询慢、同步不一致"]学习 ES 不要只背 API。每个 API 都要想清楚三个问题:
| 问题 | 为什么重要 |
|---|---|
| 为什么这样设计 | 能理解 ES 和数据库的边界 |
| 如果不用会怎样 | 能知道问题会在性能、准确性还是一致性上爆发 |
| 线上坏了怎么查 | 能从分词、Mapping、DSL、同步、集群逐层定位 |
最小 Demo:商品搜索
创建一个学习用商品索引:
json
PUT /product_search_demo
{
"mappings": {
"properties": {
"id": { "type": "long" },
"productName": {
"type": "text",
"analyzer": "standard",
"fields": {
"keyword": { "type": "keyword", "ignore_above": 256 }
}
},
"brandName": { "type": "keyword" },
"categoryName": { "type": "keyword" },
"price": { "type": "scaled_float", "scaling_factor": 100 },
"stockStatus": { "type": "keyword" },
"saleCount": { "type": "long" },
"updatedAt": { "type": "date" }
}
}
}写入商品:
json
POST /product_search_demo/_doc/1001
{
"id": 1001,
"productName": "无线蓝牙降噪耳机 Pro",
"brandName": "SoundMax",
"categoryName": "耳机",
"price": 29900,
"stockStatus": "IN_STOCK",
"saleCount": 5821,
"updatedAt": "2026-07-01T10:00:00"
}搜索并高亮:
json
GET /product_search_demo/_search
{
"query": {
"bool": {
"must": [
{ "match": { "productName": "无线降噪耳机" } }
],
"filter": [
{ "term": { "stockStatus": "IN_STOCK" } },
{ "range": { "price": { "lte": 30000 } } }
]
}
},
"sort": [
{ "_score": "desc" },
{ "saleCount": "desc" }
],
"highlight": {
"fields": {
"productName": {}
}
}
}这个 Demo 展示了商业搜索最核心的链路:设计 Mapping、写入搜索视图、关键词召回、结构化过滤、排序和高亮。
