ElasticSearch
1. 问题:关系数据库的限制
⚠️ 效率低下
带通配符的标准 LIKE 查询(例如 %laptop%)会触发全表扫描,这使得它们的计算成本很高,并且随着数据集扩展到数百万条记录而变得越来越慢。
⚠️缺乏相关性
传统的 SQL 查询返回匹配没有排名或相关性评分。这意味着结果没有优先顺序,例如,一本“关于”机器学习的书与仅简要提及它的书被视为相同。
⚠️ 可扩展性问题
随着系统扩展(例如,亚马逊或谷歌等平台),需要亚毫秒级搜索延迟。传统的关系数据库很难有效地满足这些性能需求。
用于搜索的关系数据库的其他限制
⚠️ 全文搜索支持不佳
关系数据库并非专为高级全文搜索功能而设计,例如:
- 代币化
- 词干提取(例如,“运行”→“运行”)
- 同义词处理
与专用搜索引擎相比,这使得搜索不太智能。
⚠️没有内置排名算法
没有对相关性评分算法(例如 TF-IDF 或 BM25)的本机支持,而这些算法对于对搜索结果进行有意义的排名至关重要。
⚠️ 难以处理拼写错误和模糊搜索
关系数据库面临以下问题:
- 拼写错误(例如,“laptpo”而不是“laptop”)
- 近似匹配
实现模糊搜索既复杂又低效。
⚠️ 有限的水平可扩展性
扩展关系数据库通常意味着垂直扩展(为一台机器添加更多功能),而现代搜索系统需要水平扩展(分布式系统)。
⚠️ 复杂查询的高延迟
结合过滤器+排序+文本搜索会导致:
- 查询执行速度慢
- 增加数据库负载
⚠️ 未针对读取繁重的工作负载进行优化
搜索系统读取繁重,但关系数据库针对**事务工作负载(CRUD)**进行优化,而不是针对高速搜索查询。
⚠️ 索引限制
虽然存在索引(B 树等),但它们并未针对以下方面进行优化:
- 全文搜索
- 倒排索引(用于搜索引擎)
⚠️ 实时搜索挑战
与 Elasticsearch 等系统相比,更新索引并在搜索结果中立即反映变化更加困难。
2. 解决方案:倒排索引 (8:48 - 16:12)
概念
该系统不是为每个搜索查询扫描整个文档,而是使用倒排索引 - 一种专门的数据结构,将每个术语(单词)映射到它出现的文档列表。
👉 将其视为书籍索引:
- 不必阅读整本书来查找单词
- 直接在索引中查找单词并跳转到页面
传统方法(效率低下)
扫描每个文档 → 检查它是否包含“laptop
####倒排索引方法(高效)
“笔记本电脑”→ [doc1、doc7、doc21、doc105]
因此,系统不会搜索所有文档,而是直接检索相关文档。
内部如何运作
代币化
- 文本被分解为单独的术语(标记)
- 示例:
"Gaming Laptop under 50k"→["gaming", "laptop", "under", "50k"]
标准化
- 转换为小写,删除标点符号等。
"Laptop"→"laptop"
索引创建
- 每个令牌都存储有文档 ID 列表
笔记本电脑 → [doc1、doc3、doc10]
游戏 → [doc1, doc8]
- 每个令牌都存储有文档 ID 列表
搜索
- 查询也被标记化
- 立即从索引中获取匹配的文档
🚀 为什么它如此强大
极速搜索
无需全表扫描——直接查找大规模高效
即使处理数百万/数十亿的文档也能正常工作支持高级功能
全文搜索
排名(TF-IDF、BM25)
模糊搜索(拼写错误)
短语匹配
⚙️技术
Elasticsearch 使用 Apache Lucene 作为其核心引擎。
Apache Lucene 处理:
倒排索引创建
查询处理
排名和评分
Elasticsearch 添加:
REST API
分布式架构
横向可扩展性
🆚 与关系型数据库的比较
| 特色 | 关系数据库 (LIKE) |
倒排索引 |
|---|---|---|
| 搜索方法 | 全面扫描 | 直接查找 |
| 速度 | 慢 | 快⚡ |
| 相关性排名 | ❌ 否 | ✅ 是的 |
| 可扩展性 | 有限公司 | 高🚀 |
3. 搜索智能 (16:12 - 22:05)
现代搜索引擎不仅仅是寻找匹配,它们还专注于提供最相关的结果。这是通过先进的排名算法和智能查询处理来实现的。
🧠 相关性评分(BM25 算法)
Elasticsearch 等搜索引擎使用 BM25(最佳匹配 25) 算法根据文档与查询的相关程度对文档进行排名。
BM25 没有平等对待所有匹配项,而是使用多个因素为每个文档分配 分数:
📌 1. 词频 (TF)
- 测量搜索词在文档中出现的频率
- 更高的频率→更高的相关性
👉 示例:
- 文档 A:“笔记本电脑笔记本电脑”→ 更相关
- Doc B:“笔记本电脑”(仅一次)→ 不太相关
📌 2. 文档频率 (DF)
- 衡量某个术语在所有文档中的常见程度
- 稀有术语比常见术语更有价值
👉 示例:
- “笔记本电脑”(常用词)→ 影响较小
- “ultrabook”(罕见词)→ 更高的影响力
这有助于系统避免高估通用词。
📌 3. 场增强
- 并非所有领域都同等重要
- 某些领域的比赛被赋予更高的权重
👉 示例:
- 匹配标题 → 非常重要
- 匹配描述/内容 → 不太重要
标题:“最佳游戏笔记本电脑” ✅ 高优先级
描述:“…包括笔记本电脑…” ❌ 较低优先级
🤖 拼写错误容错和查询智能
现代搜索引擎可以理解用户意图,即使查询不完美。
🔍特点:
模糊搜索(拼写错误处理)
检测并纠正拼写错误
“笔记本电脑”→“笔记本电脑”“您是说”建议
输入错误时建议更正查询自动完成/建议
实时预测用户正在输入的内容
🚀 为什么这很重要
- 用户立即获得准确的结果
- 显着改善用户体验
- 对于以下平台至关重要:
- 电子商务(亚马逊)
- 搜索引擎(谷歌)
- 求职门户、博客、SaaS 应用程序
🆚 没有搜索智能
| 场景 | 没有BM25 | 与BM25 |
|---|---|---|
| 关键词精准匹配 | 同等级 | 排名 |
| 重要字段(标题与正文) | 被忽略 | 优先 |
| 罕见词与常见词 | 相同重量 | 平衡 |
| 打字错误 | ❌ 失败 | ✅ 已处理 |
4. 实际基准测试
🧪 测试用例
PostgreSQL 和 Elasticsearch 之间的性能比较是使用 50,000 条记录的数据集进行的。
⏱️ 结果:
- PostgreSQL → ~7.5 秒
- Elasticsearch → ~500 毫秒
👉 这表明使用 Elasticsearch 等搜索优化引擎时性能大幅提升。
为什么有区别?
PostgreSQL
- 使用传统查询(
LIKE、连接等) - 经常执行完整或部分扫描
- 未针对大规模全文搜索进行优化
- 使用传统查询(
弹性搜索
- 使用倒排索引
- 执行直接查找而不是扫描
- 针对快速、实时搜索查询进行了优化
要点
一、掌握SQL和数据库优化
- 索引
- 查询优化
- 架构设计
然后,在以下情况下使用 Elasticsearch(或类似工具):
- 您的应用程序搜索量较大
- 您需要以下功能:
- 提前输入(自动完成)
- 全文搜索
- 高级过滤和排名
- 实时搜索体验
何时使用什么?
| 使用案例 | PostgreSQL | 弹性搜索 |
|---|---|---|
| CRUD 操作 | ✅ | ❌ |
| 交易系统 | ✅ | ❌ |
| 简单搜索 | ✅ | ❌ |
| 全文检索 | ⚠️ 有限公司 | ✅ |
| 高性能搜索 | ❌ | ✅ |
| 自动完成/建议 | ❌ | ✅ |