Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← Web 开发 / Web Development

中间件 / Middleware

1. Web 中间件全景 / The Web Middleware Landscape

2. 中间件——流量洪峰下的系统保护 / Middleware for Protecting Systems Under Traffic Spikes

cache layer

1. 缓存架构全景 / Cache Architecture Overview

2. Redis 深入——为什么你的缓存总是出问题 / Redis Internals and Cache Failure Modes

3. Redis 数据结构场景应用——什么时候用什么 / Choosing Redis Data Structures for Real Applications

4. 缓存策略——库存变了,缓存怎么处理 / Cache Strategies and Inventory Consistency

5. Redis 缓存三剑客——穿透/击穿/雪崩 + 一致性策略 / Redis Cache Penetration, Breakdown, Avalanche, and Consistency

6. Redis 分布式锁——从 SETNX 到 Redisson / Redis Distributed Locks from SETNX to Redisson

7. Redis Cluster 与 Sentinel 高可用架构 / Redis Cluster and Sentinel High-Availability Architecture

8. Redis 高级特性——Stream / PubSub / Module / LLM 应用

9. Redis 架构深度分析——为什么 Redis 能这么快 / Redis Architecture and the Sources of Its Performance

10. Redis 全景——为什么你的系统需要一个缓存层 / The Redis Landscape and Why Systems Need a Cache Layer

message queue

1. 消息队列全景——为什么你的系统需要一个中间人 / Message Queue Overview and Why Your System Needs a Middleman

2. Kafka 核心——为什么你的消息总是"丢"了 / Kafka Fundamentals and Message Delivery Semantics

3. 消息队列高级——死信队列、延迟消息、消息积压 / Advanced Messaging with Dead Letters, Delays, and Backlogs

4. Kafka Streams 与 Connect —— 让数据自己流动起来 / Kafka Streams and Connect for Streaming Data Pipelines

5. RabbitMQ 深度解析 —— 灵活路由与消息可靠性 / RabbitMQ Deep Dive into Flexible Routing and Reliability

6. 消息队列对比——为什么最终选了 Kafka / Comparing Message Queues and Choosing Kafka

search engine

1. 搜索引擎知识体系 / Search Engine Knowledge System

2. Elasticsearch——为什么 Like 查询总是那么慢 / Elasticsearch for Full-Text Search at Scale

3. Elasticsearch 查询 DSL 深入——为什么你的搜索总是不准 / Elasticsearch Query DSL Deep Dive

4. Elasticsearch 集群规划与运维——为什么你的集群总是"黄" / Elasticsearch Cluster Planning and Operations

5. Meilisearch 与轻量搜索替代方案——当 ES 太重时 / Meilisearch and Lightweight Search Alternatives

infrastructure

1. 基础设施组件全景 / Infrastructure Components Landscape

2. Nginx 与反向代理 / Nginx and Reverse Proxy

3. 服务发现 / Service Discovery

4. 配置中心 / Configuration Center

本页目录

搜索引擎知识体系 / Search Engine Knowledge System ​

📅 创建时间:2026-07-28 🏷️ 标签:#搜索引擎 #Elasticsearch #Meilisearch #倒排索引 #全文搜索 #向量搜索 📚 前置知识:[[../../00-overview]](中间件全景) [[../../06-databases-and-data-access/00-overview]](数据库基础)


📋 本章目标 ​

  • 理解搜索的三种范式演变:数据库 LIKE → 全文索引 → 向量搜索
  • 掌握倒排索引的核心原理:分词、倒排表、跳表、词典
  • 理解搜索引擎的五大核心组件及其协作方式
  • 能够对比 Elasticsearch、Meilisearch、OpenSearch、Typesense 的差异与适用场景
  • 掌握搜索架构设计:应用层 → 搜索服务 → 索引 → 数据源同步
  • 理解索引策略的核心决策:Mapping 设计、分词器选择、Field 类型

第1部分:搜索的三种范式 ​

1.1 搜索问题的本质 ​

搜索不是一个技术问题,而是一个匹配问题:用户脑子里有一个"意图",系统里有一堆"数据",搜索就是把意图和数据匹配起来。

┌─────────────────────────────────────────────────────────────┐
│                    搜索的本质:意图匹配                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  用户侧                         系统侧                      │
│  ┌──────────────────┐    ┌──────────────────────────────┐  │
│  │ 脑子里的"意图"     │    │ 数据库里的"文档"              │  │
│  │                  │    │                              │  │
│  │ "我要买个           │    │ {name: "小米 13 Pro"}        │  │
│  │  小米手机"    ─────┼───→│ {name: "红米 Note 12"}       │  │
│  │                  │    │ {name: "iPhone 15"}           │  │
│  │ 实际上想找:       │    │ {name: "Xiaomi 13"}          │  │
│  │ "小米13系列"       │    │                              │  │
│  └──────────────────┘    └──────────────────────────────┘  │
│                                                             │
│  矛盾:用户说的 ≠ 用户想的 ≠ 系统存的                      │
│                                                             │
│  搜索就是在"说的"和"存的"之间找到最匹配的那条。             │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

1.2 范式一:数据库 LIKE —— 字符级别的暴力匹配 ​

┌─────────────────────────────────────────────────────────────┐
│                    范式一:数据库 LIKE                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  实现方式:                                                 │
│  SELECT * FROM products                                    │
│  WHERE name LIKE '%小米手机%'                              │
│                                                             │
│  匹配逻辑:字符级别的子串匹配                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  "小米 13 手机" 包含 "小米手机" 吗?                  │   │
│  │  逐字符比对:小=小 ✓ 米=米 ✓ 手机≠13 ✗               │   │
│  │  结果:不匹配!                                      │   │
│  │                                                      │   │
│  │  用户搜"小米手机"找不到"小米 13 手机"                 │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  致命缺陷:                                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  1. 无法处理词汇变体                                   │   │
│  │     "跑" ≠ "跑步" ≠ "跑了" ≠ "跑着"               │   │
│  │                                                      │   │
│  │  2. 无法处理顺序差异                                   │   │
│  │     "小米手机" ≠ "手机小米"                           │   │
│  │                                                      │   │
│  │  3. 全表扫描,不可扩展                                 │   │
│  │     100 万行 LIKE '%x%' → 100 万次磁盘 IO            │   │
│  │                                                      │   │
│  │  4. 无相关性排序                                       │   │
│  │     所有匹配结果一视同仁,无法知道哪个更相关            │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

1.3 范式二:全文索引 —— 词汇级别的倒排匹配 ​

┌─────────────────────────────────────────────────────────────┐
│                    范式二:全文索引                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  核心思路:不再按字符匹配,而是按"词"匹配                    │
│                                                             │
│  索引构建过程:                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  文档: "小米 13 手机,性价比很高"                     │   │
│  │         ↓ 分词                                        │   │
│  │  词汇: [小米, 13, 手机, 性价比, 很高]                 │   │
│  │         ↓ 建倒排索引                                  │   │
│  │  小米   → [文档1]                                    │   │
│  │  13     → [文档1]                                    │   │
│  │  手机   → [文档1]                                    │   │
│  │  性价比 → [文档1]                                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  搜索过程:                                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  用户输入: "小米手机"                                  │   │
│  │         ↓ 分词                                        │   │
│  │  查询词: [小米, 手机]                                 │   │
│  │         ↓ 查倒排索引                                  │   │
│  │  小米 → [文档1, 文档5, 文档9]                        │   │
│  │  手机 → [文档1, 文档3, 文档7]                        │   │
│  │         ↓ 取交集                                      │   │
│  │  结果: [文档1] → "小米 13 手机" ← 找到了!          │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  关键突破:                                                 │
│  • 分词后,"小米手机"和"小米 13 手机"都能匹配              │
│  • 倒排索引让查找从 O(n) 降到 O(1)                         │
│  • 可以计算相关性得分(TF-IDF / BM25)                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

1.4 范式三:向量搜索 —— 语义级别的相似度匹配 ​

┌─────────────────────────────────────────────────────────────┐
│                    范式三:向量搜索                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  核心思路:把文字映射到高维向量空间,用距离衡量语义相似度    │
│                                                             │
│  索引构建过程:                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  文档: "小米 13 手机"                                 │   │
│  │         ↓ Embedding 模型(如 text-embedding-3-small) │   │
│  │  向量: [0.23, -0.15, 0.78, ..., 0.42]  (1536维)     │   │
│  │         ↓ 存入向量数据库                               │   │
│  │  ANN 索引(近似最近邻)                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  搜索过程:                                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  用户输入: "性价比高的安卓机"                          │   │
│  │         ↓ Embedding                                    │   │
│  │  查询向量: [0.21, -0.18, 0.75, ..., 0.40]            │   │
│  │         ↓ 向量相似度计算(余弦相似度)                  │   │
│  │  结果: "小米 13 手机" ← 即使没有相同词汇!            │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  三种范式的适用边界:                                       │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                    │ LIKE    │ 全文索引 │ 向量搜索   │   │
│  │  ─────────────────┼─────────┼─────────┼──────────  │   │
│  │  精确匹配          │ ✅      │ ✅      │ ❌         │   │
│  │  词汇变体           │ ❌      │ ✅*     │ ✅         │   │
│  │  语义理解           │ ❌      │ ❌      │ ✅         │   │
│  │  多语言             │ ❌      │ ✅*     │ ✅         │   │
│  │  可解释性           │ ✅      │ ✅      │ ❌         │   │
│  │  速度               │ 慢      │ 快      │ 中        │   │
│  │  资源消耗           │ 低      │ 中      │ 高        │   │
│  │  *依赖分词器质量                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

1.5 三种范式的演进关系 ​

┌─────────────────────────────────────────────────────────────┐
│                    搜索范式的演进路线                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  2000s          2010s          2020s          未来          │
│  ┌──────┐     ┌──────┐      ┌──────┐      ┌──────┐       │
│  │ LIKE │ ──→ │ 倒排  │ ──→ │ 向量  │ ──→ │ 混合  │       │
│  │      │     │ 索引  │      │ 搜索  │      │ 搜索  │       │
│  └──────┘     └──────┘      └──────┘      └──────┘       │
│     │             │              │              │          │
│     ▼             ▼              ▼              ▼          │
│  字符匹配     词汇匹配       语义匹配      多路融合        │
│  精确但死板   灵活但依赖      智能但黑盒    兼收并蓄        │
│              分词质量                                        │
│                                                             │
│  今天的主流:全文索引 + 向量搜索 = 混合搜索(Hybrid Search)│
│  • Elasticsearch 8.x+ 内置向量搜索                          │
│  • 先用倒排索引做关键词召回,再用向量做语义精排             │
│  • 结合两者优势:精确 + 语义                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

第2部分:倒排索引原理 ​

2.1 从文档到倒排表 ​

倒排索引是全文搜索引擎的基石。理解它不需要任何 ES 知识——它就是一本"词汇 → 页码"的字典。

┌─────────────────────────────────────────────────────────────┐
│                    倒排索引的构建过程                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  原始文档集合:                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  Doc1: "Elasticsearch is a search engine"            │   │
│  │  Doc2: "Meilisearch is fast"                         │   │
│  │  Doc3: "Elasticsearch engine is powerful"            │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Step 1: 分词(Tokenization)                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  Doc1 → [elasticsearch, is, a, search, engine]       │   │
│  │  Doc2 → [meilisearch, is, fast]                      │   │
│  │  Doc3 → [elasticsearch, engine, is, powerful]        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Step 2: 规范化(Normalization)—— 小写、词干提取         │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  Elasticsearch → elasticsearch                       │   │
│  │  running → run(词干提取 stemming)                  │   │
│  │  better → good(词形还原 lemmatization)             │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Step 3: 构建倒排表(Inverted Index)                      │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  Term            │ Posting List (文档ID列表)         │   │
│  │  ────────────────┼────────────────────────────────── │   │
│  │  elasticsearch   │ [1, 3]                           │   │
│  │  search          │ [1]                              │   │
│  │  engine          │ [1, 3]                           │   │
│  │  meilisearch     │ [2]                              │   │
│  │  fast            │ [2]                              │   │
│  │  powerful        │ [3]                              │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Step 4: 排序(Sort)—— 按 Term 字典序排列以便二分查找    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  elasticsearch → [1, 3]                             │   │
│  │  engine        → [1, 3]                             │   │
│  │  fast          → [2]                                │   │
│  │  meilisearch   → [2]                                │   │
│  │  powerful      → [3]                                │   │
│  │  search        → [1]                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

2.2 Posting List 的数据结构 ​

Posting List(倒排列表)不只存文档 ID,还存位置、词频等元信息:

┌─────────────────────────────────────────────────────────────┐
│                    Posting List 完整结构                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Term: "elasticsearch"                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  DocID │ TF  │ Positions  │  Fields                 │   │
│  │  ──────┼─────┼────────────┼──────────────────────   │   │
│  │  1     │ 1   │ [0]        │  title                  │   │
│  │  3     │ 1   │ [0]        │  title                  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  DocID: 文档唯一 ID                                         │
│  TF (Term Frequency): 该词在该文档中出现的次数              │
│  Positions: 该词在文档中的位置(用于短语查询)              │
│  Fields: 该词出现在文档的哪些字段中                          │
│                                                             │
│  这些元信息支撑了:                                         │
│  • 短语查询:"search engine" 要求两个词相邻                 │
│  • 字段权重:title 匹配比 body 匹配更重要                   │
│  • 相关性评分:TF-IDF / BM25 依赖词频数据                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

2.3 跳表(Skip List)—— 加速多词查询 ​

当查询包含多个词时,需要对多个 Posting List 取交集。跳表避免了对短列表的完整扫描。

┌─────────────────────────────────────────────────────────────┐
│                    跳表加速取交集                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  查询: "elasticsearch engine"                               │
│                                                             │
│  elasticsearch → [1, 3, 7, 12, 15, 20, 25, 30, ...100]    │
│  engine        → [3, 8, 15, 22, 30, ...80]                │
│                                                             │
│  无跳表时:O(len(A) + len(B))—— 需要扫描每个元素           │
│                                                             │
│  有跳表时:                                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  elasticsearch posting list (带跳表):                 │   │
│  │  [1] →→→→→→ [15] →→→→→→ [30] →→→ ...               │   │
│  │   ↓     ↗    ↓      ↗    ↓                           │   │
│  │  [3,7,12]   [20,25]   [35,40,...]                   │   │
│  │                                                      │   │
│  │  查询 engine=3:                                     │   │
│  │  1) 检查 elasticsearch[0]=1,1 < 3,跳!              │   │
│  │  2) 跳到 15,15 > 3,回退到区间 [3,7,12]             │   │
│  │  3) 找到 3,匹配!                                   │   │
│  │                                                      │   │
│  │  跳过了大量中间元素,大幅减少比较次数                   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ES 使用跳表 + BitSet 两种策略:                            │
│  • 跳表:适合长列表且分布稀疏的场景                         │
│  • BitSet:适合稠密列表,用位运算取交集(极快)            │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

2.4 词典(Term Dictionary)与 Term Index ​

┌─────────────────────────────────────────────────────────────┐
│                    词典与 Term Index                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  查一个词"elasticsearch"在不在索引里,不能线性扫描所有词     │
│                                                             │
│  解决方案:FST (Finite State Transducer) —— ES 的核心魔法   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  Term Index (FST, 内存)                              │   │
│  │  ┌─────────────────────────────────────────────┐    │   │
│  │  │  前缀: "ela"  → 指向磁盘上某个 block         │    │   │
│  │  │  前缀: "eng"  → 指向磁盘上某个 block         │    │   │
│  │  │  前缀: "mei"  → 指向磁盘上某个 block         │    │   │
│  │  └─────────────────────────────────────────────┘    │   │
│  │         ↓ 定位到磁盘 block                            │   │
│  │  Term Dictionary (磁盘,按 block 组织)               │   │
│  │  ┌─────────────────────────────────────────────┐    │   │
│  │  │  elasticsearch → 指向 Posting List 的指针   │    │   │
│  │  │  engine        → 指向 Posting List 的指针   │    │   │
│  │  │  fast          → 指向 Posting List 的指针   │    │   │
│  │  └─────────────────────────────────────────────┘    │   │
│  │         ↓ 通过指针读取                                 │   │
│  │  Posting Lists (磁盘)                                │   │
│  │  ┌─────────────────────────────────────────────┐    │   │
│  │  │  elasticsearch: [1, 3, 7, 12, ...]          │    │   │
│  │  └─────────────────────────────────────────────┘    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  FST 的优势:                                               │
│  • 极高的压缩率:共享前缀,比 HashMap 小 10-20 倍          │
│  • 支持前缀查询:给出"ela"即可定位到 elasticsearch 附近    │
│  • 常驻内存:虽然索引数据在磁盘,但词典可以全放内存         │
│                                                             │
│  为什么 Lucene/ES 能在 TB 级数据上毫秒级响应?              │
│  答案:FST 词典 + 跳表/BitSet + OS Page Cache               │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

第3部分:搜索引擎核心组件 ​

3.1 五大核心组件全景 ​

┌─────────────────────────────────────────────────────────────┐
│                    搜索引擎核心组件架构                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  用户查询                                                   │
│     ↓                                                      │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  ① 分词器 (Tokenizer/Analyzer)                      │   │
│  │  把"小米13手机"拆成 → [小米, 13, 手机]               │   │
│  └─────────────────────────┬───────────────────────────┘   │
│                            ↓                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  ② 查询解析器 (Query Parser)                        │   │
│  │  把 "price:[100 TO 500] AND brand:小米"              │   │
│  │  解析成 AST 语法树                                   │   │
│  └─────────────────────────┬───────────────────────────┘   │
│                            ↓                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  ③ 相关性评分 (Scoring)                             │   │
│  │  BM25 / TF-IDF 计算每个文档与查询的匹配度            │   │
│  └─────────────────────────┬───────────────────────────┘   │
│                            ↓                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  ④ 排序与过滤 (Sorting & Filtering)                 │   │
│  │  按 score 排序 + 应用 filter 条件 + 分页             │   │
│  └─────────────────────────┬───────────────────────────┘   │
│                            ↓                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  ⑤ 结果高亮与聚合 (Highlighting & Aggregation)      │   │
│  │  高亮匹配片段 + Facet 统计 + 聚合分析                │   │
│  └─────────────────────────────────────────────────────┘   │
│     ↓                                                      │
│  返回给用户                                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

3.2 分词器(Analyzer)的组成 ​

┌─────────────────────────────────────────────────────────────┐
│                    分词器三件套                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Analyzer = Character Filter → Tokenizer → Token Filter     │
│                                                             │
│  示例:处理 HTML 文本 "<p>Hello World!</p>"                │
│                                                             │
│  Step 1: Character Filter(字符过滤器)                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  输入: "<p>Hello World!</p>"                         │   │
│  │  html_strip: 去掉 HTML 标签                          │   │
│  │  输出: "Hello World!"                                │   │
│  └─────────────────────────────────────────────────────┘   │
│         ↓                                                   │
│  Step 2: Tokenizer(分词器)                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  输入: "Hello World!"                                │   │
│  │  standard: 按空格和标点拆分                          │   │
│  │  输出: [Hello, World]                                │   │
│  └─────────────────────────────────────────────────────┘   │
│         ↓                                                   │
│  Step 3: Token Filter(词元过滤器)                        │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  输入: [Hello, World]                                │   │
│  │  lowercase: 转小写 → [hello, world]                 │   │
│  │  stop: 去掉停用词(is, the, a...)                  │   │
│  │  输出: [hello, world]                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  中文分词器特别重要(中文没有空格分隔):                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  ik_max_word (IK 分词器,细粒度):                    │   │
│  │  "中华人民共和国" → [中华人民共和国, 中华人民,      │   │
│  │                      中华, 华人, 人民共和国,         │   │
│  │                      人民, 共和国, 共和, 国]         │   │
│  │                                                      │   │
│  │  ik_smart (IK 分词器,粗粒度):                       │   │
│  │  "中华人民共和国" → [中华人民共和国]                  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

3.3 查询解析器(Query Parser) ​

┌─────────────────────────────────────────────────────────────┐
│                    查询解析流程                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  用户输入(可能是自然语言、关键词、或 DSL):               │
│  "小米手机 AND 价格:<5000 NOT 二手"                         │
│         ↓                                                   │
│  词法分析:拆成 Token                                      │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  [小米手机, AND, 价格:<5000, NOT, 二手]             │   │
│  └─────────────────────────────────────────────────────┘   │
│         ↓                                                   │
│  语法分析:构建 AST                                        │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              AND                                    │   │
│  │             /   \                                   │   │
│  │       TermQuery  NOT                               │   │
│  │      "小米手机"    \                                │   │
│  │                  RangeQuery                         │   │
│  │                  价格<5000                           │   │
│  └─────────────────────────────────────────────────────┘   │
│         ↓                                                   │
│  生成 Lucene Query 对象                                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  BooleanQuery(must=[TermQuery("小米手机"),           │   │
│  │                      RangeQuery(0-5000)],           │   │
│  │               must_not=[TermQuery("二手")])          │   │
│  └─────────────────────────────────────────────────────┘   │
│         ↓                                                   │
│  执行查询 → 倒排索引取交集 → 评分 → 排序 → 返回            │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

3.4 相关性评分(BM25) ​

┌─────────────────────────────────────────────────────────────┐
│                    从 TF-IDF 到 BM25                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  TF-IDF(老方案,ES 5.x 前):                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  Score = TF × IDF                                   │   │
│  │                                                      │   │
│  │  TF (词频): 词在文档中出现的次数                      │   │
│  │    → 问题:出现 100 次 ≠ 100 倍相关                  │   │
│  │                                                      │   │
│  │  IDF (逆文档频率): log(总文档数 / 包含词的文档数)    │   │
│  │    → 出现越少的词越重要("elasticsearch" vs "is")   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  BM25(当前标准,ES 5.x+):                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  Score = IDF × (TF × (k1 + 1)) / (TF + k1 × (...))  │   │
│  │                                                      │   │
│  │  改进点:                                             │   │
│  │  1. 词频饱和:TF 增加到一定程度后不再增加分数        │   │
│  │     → 一篇文档写 100 个"手机",不会比写 5 个高20倍  │   │
│  │                                                      │   │
│  │  2. 文档长度归一化:长文档不会被"惩罚"过度           │   │
│  │     → 比 TF-IDF 更公平地对待不同长度的文档           │   │
│  │                                                      │   │
│  │  3. 可调参数:k1(词频饱和度)和 b(长度归一化程度) │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

第4部分:搜索引擎全景对比 ​

4.1 四大搜索引擎定位 ​

┌─────────────────────────────────────────────────────────────┐
│                    搜索引擎选型全景对比                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│              Elasticsearch   OpenSearch    Meilisearch  Typesense
│  ──────────┼──────────────────────────────────────────────
│  起源       │ 2010, Shay    2021, AWS    2018, 法国    2015, 印度
│             │  Banon         Fork ES      Rust 编写    C++ 编写
│  ──────────┼──────────────────────────────────────────────
│  许可证     │ SSPL/Elastic   Apache 2.0   MIT          GPLv3
│  ──────────┼──────────────────────────────────────────────
│  定位       │ 全文搜索 +     ES 的开源    轻量即时     轻量即时
│             │ 分析引擎       替代品       搜索          搜索
│  ──────────┼──────────────────────────────────────────────
│  适用规模   │ PB 级          PB 级        TB 级        TB 级
│  ──────────┼──────────────────────────────────────────────
│  部署难度   │ 高             高           极低          低
│  ──────────┼──────────────────────────────────────────────
│  内存需求   │ 2GB+ (heap)    2GB+ (heap)  512MB+       512MB+
│  ──────────┼──────────────────────────────────────────────
│  搜索延迟   │ <100ms         <100ms       <50ms        <50ms
│  ──────────┼──────────────────────────────────────────────
│  聚合分析   │ 极强           极强         有限          有限
│  ──────────┼──────────────────────────────────────────────
│  中文支持   │ IK 分词器      IK 分词器    内置 Jieba   内置
│  ──────────┼──────────────────────────────────────────────
│  向量搜索   │ ✓ (8.x+)      ✓ (2.x+)     ✗ (实验性)   ✗ (实验性)
│  ──────────┼──────────────────────────────────────────────
│  SQL 支持   │ ✓              ✓            ✗             ✗
│  ──────────┼──────────────────────────────────────────────
│  适用场景   │ 日志分析       ES 替代      站内搜索      SaaS 搜索
│             │ 企业搜索       合规要求     即时搜索     电商搜索
│             │ 指标聚合       成本敏感     文档搜索     文档搜索
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

4.2 核心差异:使用场景矩阵 ​

┌─────────────────────────────────────────────────────────────┐
│                    场景 → 引擎映射                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  场景                      推荐引擎          原因          │
│  ─────────────────────────────────────────────────────     │
│  电商商品搜索(百万 SKU)   ES / OpenSearch   聚合+过滤强   │
│  博客/文档站内搜索          Meilisearch       部署简单      │
│  日志分析(ELK Stack)      ES                生态完整      │
│  SaaS 产品内置搜索          Typesense          易于嵌入      │
│  合规要求(Apache 2.0)     OpenSearch         许可证友好    │
│  小项目/个人项目            Meilisearch        零配置        │
│  RAG 应用的知识库搜索       ES/OpenSearch     向量搜索成熟  │
│  实时 Dashboard 搜索        Typesense          速度极快      │
│                                                             │
│  一句话总结:                                               │
│  • 需要分析能力?→ ES / OpenSearch                         │
│  • 只需要搜索?→ Meilisearch / Typesense                   │
│  • 担心许可证?→ OpenSearch / Meilisearch                  │
│  • 追求开发体验?→ Meilisearch                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

第5部分:搜索架构设计 ​

5.1 经典搜索架构 ​

┌─────────────────────────────────────────────────────────────┐
│                    搜索系统整体架构                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                    应用层 (App)                      │   │
│  │  ┌────────────────┐  ┌────────────────────────┐     │   │
│  │  │  搜索 UI       │  │  管理后台              │     │   │
│  │  │  (搜索框+结果)  │  │  (索引管理+同义词)     │     │   │
│  │  └───────┬────────┘  └───────────┬────────────┘     │   │
│  └──────────┼──────────────────────┼───────────────────┘   │
│             │                      │                       │
│             ▼                      ▼                       │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                搜索服务层 (Search Service)           │   │
│  │                                                     │   │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────────────┐   │   │
│  │  │ 查询构建 │ │ 结果处理 │ │ 索引管理          │   │   │
│  │  │          │ │          │ │                  │   │   │
│  │  │ • 分词   │ │ • 高亮   │ │ • bulk 写入      │   │   │
│  │  │ • 纠错   │ │ • 排序   │ │ • reindex        │   │   │
│  │  │ • 改写   │ │ • 分页   │ │ • alias 切换     │   │   │
│  │  │ • 过滤   │ │ • 聚合   │ │ • mapping 更新   │   │   │
│  │  └─────┬────┘ └────┬─────┘ └────────┬─────────┘   │   │
│  └────────┼───────────┼───────────────┼───────────────┘   │
│           │           │               │                    │
│           ▼           ▼               ▼                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              搜索引擎集群 (ES / Meilisearch)         │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐              │   │
│  │  │  Node 1 │ │  Node 2 │ │  Node 3 │              │   │
│  │  │ Shard 0 │ │ Shard 1 │ │ Shard 2 │              │   │
│  │  └─────────┘ └─────────┘ └─────────┘              │   │
│  └────────────────┬────────────────────────────────────┘   │
│                   │                                        │
│                   ▼                                        │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                  数据源同步                          │   │
│  │                                                     │   │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────────┐     │   │
│  │  │ CDC      │  │ 定时全量 │  │ 应用双写     │     │   │
│  │  │ (Canal,  │  │ 同步     │  │              │     │   │
│  │  │  Debezium│  │ (cron)   │  │              │     │   │
│  │  └─────┬────┘  └────┬─────┘  └──────┬───────┘     │   │
│  │        │            │               │               │   │
│  │        ▼            ▼               ▼               │   │
│  │  ┌──────────────────────────────────────────────┐   │   │
│  │  │          主数据库 (MySQL / PostgreSQL)        │   │   │
│  │  └──────────────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

5.2 数据同步策略对比 ​

┌─────────────────────────────────────────────────────────────┐
│                    三种同步策略对比                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  策略1:应用双写                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  应用代码:                                            │   │
│  │  db.save(product);           // 写数据库              │   │
│  │  es.index(product);          // 同时写 ES             │   │
│  │                                                      │   │
│  │  优点:实时性最高                                      │   │
│  │  缺点:数据一致性难以保证,ES 写入失败需要补偿        │   │
│  │  适用:对实时性要求极高的小规模场景                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  策略2:CDC (Change Data Capture)                           │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  MySQL binlog → Canal/Debezium → Kafka → ES Sink    │   │
│  │                                                      │   │
│  │  优点:解耦、可靠、可回溯、不侵入业务代码              │   │
│  │  缺点:引入 Kafka + Canal 等额外组件,运维复杂        │   │
│  │  适用:中大型项目,有运维能力的团队                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  策略3:定时全量/增量同步                                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  cron job → SELECT * FROM products                  │   │
│  │           WHERE updated_at > :last_sync             │   │
│  │           → bulk index to ES                        │   │
│  │                                                      │   │
│  │  优点:实现简单,无需额外组件                          │   │
│  │  缺点:有延迟(分钟级),全量同步资源消耗大           │   │
│  │  适用:对实时性要求不高(分钟级延迟可接受)的场景     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

第6部分:索引策略 ​

6.1 Mapping 设计核心原则 ​

┌─────────────────────────────────────────────────────────────┐
│                    Mapping 设计决策树                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  这个字段用来做什么?                                  │   │
│  │   ├── 全文搜索  → text + 配置分词器                   │   │
│  │   ├── 精确匹配  → keyword                            │   │
│  │   ├── 范围查询  → integer / long / date              │   │
│  │   ├── 排序      → keyword / numeric                 │   │
│  │   ├── 聚合      → keyword / numeric                 │   │
│  │   └── 不需要搜索 → enabled: false (节省空间)        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Mapping 示例(商品搜索):                                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  {                                                    │   │
│  │    "properties": {                                    │   │
│  │      "title": {                                       │   │
│  │        "type": "text",             // 全文搜索        │   │
│  │        "analyzer": "ik_max_word",  // 中文分词        │   │
│  │        "fields": {                                    │   │
│  │          "keyword": {              // 精确匹配 + 排序 │   │
│  │            "type": "keyword"                          │   │
│  │          }                                            │   │
│  │        }                                              │   │
│  │      },                                               │   │
│  │      "price": {"type": "float"},   // 范围查询        │   │
│  │      "category": {"type": "keyword"}, // 精确匹配     │   │
│  │      "created_at": {"type": "date"},  // 范围查询     │   │
│  │      "description": {                                 │   │
│  │        "type": "text",                                │   │
│  │        "analyzer": "ik_max_word"                      │   │
│  │      },                                               │   │
│  │      "stock": {                                       │   │
│  │        "type": "integer"            // 范围 + 排序    │   │
│  │      }                                                │   │
│  │    }                                                  │   │
│  │  }                                                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

6.2 常见字段类型速查 ​

┌─────────────────────────────────────────────────────────────┐
│                    ES 字段类型速查表                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  数据类型        字段用途            搜索能力              │
│  ────────────────────────────────────────────────────      │
│  text          全文索引             分词、模糊、短语        │
│  keyword       标签、ID、枚举       精确匹配、排序、聚合    │
│  integer/long  数量、ID             范围、排序、聚合        │
│  float/double  价格、评分           范围、排序、聚合        │
│  date          时间戳               范围、date_histogram    │
│  boolean       布尔标记             精确过滤                │
│  geo_point     经纬度               距离排序、范围          │
│  nested        对象数组             独立查询子对象          │
│  join          父子文档             跨文档关联查询          │
│  dense_vector  向量嵌入             相似度搜索 (kNN)        │
│  completion    自动补全             前缀匹配 (suggest)      │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

6.3 分词器选择决策 ​

┌─────────────────────────────────────────────────────────────┐
│                    分词器选择指南                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  中文场景:                                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  ik_max_word:最大化分词,召回率最高                  │   │
│  │    例:"北京大学" → [北京, 大学, 北京大学, 京大]    │   │
│  │    适用:商品搜索、内容搜索(宁可多召回也不能漏)     │   │
│  │                                                      │   │
│  │  ik_smart:最粗粒度分词,精确率最高                   │   │
│  │    例:"北京大学" → [北京大学]                       │   │
│  │    适用:特定领域搜索(法律、医学等专业术语)         │   │
│  │                                                      │   │
│  │  jieba:Python 社区流行,ES 有插件                   │   │
│  │    适用:已有 jieba 积累自定义词典的团队              │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  英文场景:                                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  standard:默认分词器,按单词边界拆分                 │   │
│  │    "running quickly" → [running, quickly]            │   │
│  │                                                      │   │
│  │  + stemmer:词干提取                                  │   │
│  │    "running" → "run", "jumped" → "jump"             │   │
│  │    适用:英文内容搜索(提高召回率)                   │   │
│  │                                                      │   │
│  │  + stop words:停用词过滤                            │   │
│  │    "the quick brown fox" → [quick, brown, fox]       │   │
│  │    适用:减少索引大小,加速搜索                       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  多语言场景:Meilisearch 表现优于 ES(内置语言检测)       │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

核心总结 ​

总结1:三种搜索范式 ​

范式一(LIKE)→ 范式二(全文索引)→ 范式三(向量搜索)
字符匹配          词汇匹配            语义匹配
简单但脆弱         成熟可靠            智能但黑盒
1
2
3

当前生产环境的主流是全文索引为主 + 向量搜索为辅的混合模式。

总结2:倒排索引核心数据结构 ​

Term Dictionary (FST, 内存)
  → Term → Posting List 指针
    → Posting List: [DocID, TF, Positions, Fields]
      → 跳表 / BitSet 加速取交集
1
2
3
4

总结3:搜索引擎选型决策 ​

条件推荐引擎
需要聚合/日志分析Elasticsearch
合规要求(Apache 2.0)OpenSearch
只需搜索、追求简单Meilisearch
SaaS 产品搜索Typesense
小型项目PostgreSQL 全文搜索

总结4:搜索架构核心原则 ​

1. ES 不是数据库——它是搜索服务的索引,数据源永远是主数据库
2. 数据同步是搜索系统最脆弱的一环——选对同步策略比调索引更重要
3. Mapping 设计决定搜索质量——花时间设计 mapping,不要用 dynamic mapping
4. 分词器是中文搜索的灵魂——IK 分词器的词典决定召回率
1
2
3
4

章节测试 ​

测试1:范式理解 ​

LIKE '%手机%' 为什么无法找到"小米 13 手机"?倒排索引是如何解决这个问题的?

测试2:倒排索引 ​

倒排索引中的 Posting List 包含哪些关键信息?每种信息支撑了什么搜索功能?

测试3:数据结构 ​

FST (Finite State Transducer) 在倒排索引中扮演什么角色?它比 HashMap 好在哪里?

测试4:分词器 ​

Analyzer 由哪三部分组成?每部分负责什么?

测试5:选型 ​

一个 10 人团队的电商项目,需要商品搜索和简单的 facet 聚合,你会选 ES 还是 Meilisearch?为什么?

测试6:同步策略 ​

什么是 CDC 同步?它比应用双写好在哪里?引入了什么代价?

测试7:Mapping ​

一个商品名称字段既是搜索的主体(需要分词),又要做 A-Z 排序(需要精确值),Mapping 应该怎么设计?


参考答案 ​

测试1答案 ​

答案:LIKE 是字符级别的子串匹配。"小米 13 手机"不包含连续子串"小米手机",所以 LIKE 找不到。倒排索引先把文档分词成 [小米, 13, 手机],再把用户输入分词成 [小米, 手机],然后对两个词分别查倒排表取交集,文档同时包含这两个词就能匹配。


测试2答案 ​

答案:

  • DocID:定位到具体文档(多词查询取交集)
  • TF (Term Frequency):词频,支撑 BM25 相关性评分
  • Positions:词在文档中的位置,支撑短语查询("search engine" 要求两个词连续)
  • Fields:词出现在哪些字段,支撑字段权重(title 比 body 重要)

测试3答案 ​

答案:FST 是 Term Dictionary 的底层数据结构,作用是将 term 映射到 Posting List 的磁盘位置。比 HashMap 好的原因:共享前缀(极高压缩率,比 HashMap 小 10-20 倍);支持前缀查询;可常驻内存。FST 是 ES 能在海量数据上毫秒级响应的关键。


测试4答案 ​

答案:

  1. Character Filter(字符过滤器):预处理原始文本(去 HTML 标签、转换特殊字符)
  2. Tokenizer(分词器):将文本拆分成词元(按空格、标点、或语言规则拆分)
  3. Token Filter(词元过滤器):对词元做后处理(小写转换、停用词过滤、词干提取)

测试5答案 ​

答案:需要 facet 聚合 → 推荐 ES(或 OpenSearch)。Meilisearch 的 facet 能力有限,适合简单筛选但不适合复杂的聚合分析。10 人团队有能力运维 ES 集群(至少比 ES 调优简单)。


测试6答案 ​

答案:CDC (Change Data Capture) 通过监听数据库 binlog/WAL 实现数据变更的实时捕获,经 Kafka 等通道写入搜索引擎。比应用双写的优势:解耦(业务代码不需要感知搜索);可靠(binlog 天然有序且不丢);可回溯(重放 binlog 重建索引)。代价:引入 Kafka、Canal/Debezium 等额外组件,增加运维复杂度;有秒级延迟。


测试7答案 ​

答案:使用 multi-field 设计:

json
{
  "title": {
    "type": "text",
    "analyzer": "ik_max_word",
    "fields": {
      "keyword": {
        "type": "keyword"
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11

搜索时用 title 字段(分词匹配),排序时用 title.keyword 字段(精确值排序)。


相关笔记 ​

  • [[/03-web/07-middleware/00-overview]] - 中间件全景
  • [[/03-web/07-middleware/06-elasticsearch]] - ES 倒排索引深入
  • [[./02-elasticsearch-queries]] - ES 查询 DSL 深入
  • [[./03-elasticsearch-cluster]] - ES 集群规划与运维
  • [[./04-meilisearch-and-alternatives]] - 轻量搜索替代方案

下一步学习 ​

  • [ ] 阅读 02 - Elasticsearch 查询 DSL
  • [ ] 阅读 03 - Elasticsearch 集群
  • [ ] 阅读 04 - Meilisearch 与替代方案

学习状态:🟡 开始学习

最后更新于:

Pager
上一篇6. 消息队列对比——为什么最终选了 Kafka / Comparing Message Queues and Choosing Kafka
下一篇2. Elasticsearch——为什么 Like 查询总是那么慢 / Elasticsearch for Full-Text Search at Scale

持续记录,持续成长

Copyright © Tidenflow