搜索引擎
问题
Elasticsearch 的核心原理是什么?如何实现全文搜索?
答案
倒排索引
传统数据库是「文档 → 词」的映射,倒排索引是「词 → 文档」的映射。
// 正排索引(MySQL)
Doc1: "React 性能优化指南"
Doc2: "Vue 性能对比分析"
// 倒排索引(Elasticsearch)
"React" → [Doc1]
"Vue" → [Doc2]
"性能" → [Doc1, Doc2]
"优化" → [Doc1]
"分析" → [Doc2]
搜索「性能」时,直接从倒排索引找到 [Doc1, Doc2],无需全表扫描。
Elasticsearch 基础操作
elasticsearch.ts
import { Client } from '@elastic/elasticsearch';
const es = new Client({ node: 'http://localhost:9200' });
// 创建索引(定义 Mapping)
await es.indices.create({
index: 'articles',
body: {
mappings: {
properties: {
title: { type: 'text', analyzer: 'ik_max_word' }, // 中文分词
content: { type: 'text', analyzer: 'ik_smart' },
tags: { type: 'keyword' }, // 不分词,用于精确匹配
publishedAt: { type: 'date' },
},
},
},
});
// 索引文档
await es.index({
index: 'articles',
body: {
title: 'React 18 新特性解析',
content: 'React 18 引入了并发渲染...',
tags: ['react', 'frontend'],
publishedAt: '2024-01-01',
},
});
// 全文搜索
const result = await es.search({
index: 'articles',
body: {
query: {
multi_match: {
query: 'React 性能',
fields: ['title^2', 'content'], // title 权重是 content 的 2 倍
},
},
highlight: {
fields: { title: {}, content: {} }, // 高亮匹配词
},
},
});
轻量替代方案
| 方案 | 特点 | 适用场景 |
|---|---|---|
| Elasticsearch | 功能强大、分布式 | 大规模全文搜索 |
| Meilisearch | 简单易用、即时搜索 | 中小应用、搜索即服务 |
| Typesense | 低延迟 | 实时搜索补全 |
| PostgreSQL 全文搜索 | 内置、无额外依赖 | 简单搜索需求 |
meilisearch.ts
// Meilisearch(更简单的替代方案)
import { MeiliSearch } from 'meilisearch';
const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'xxx' });
// 添加文档
await client.index('articles').addDocuments(articles);
// 搜索(自动处理拼写纠错、同义词)
const results = await client.index('articles').search('React 性能', {
limit: 10,
attributesToHighlight: ['title', 'content'],
});
常见面试问题
Q1: Elasticsearch 和 MySQL LIKE 的区别?
答案:
| 维度 | ES | MySQL LIKE |
|---|---|---|
| 原理 | 倒排索引 | 全表扫描 |
| 中文 | 分词后搜索 | 模糊匹配 |
| 性能 | 亿级数据毫秒返回 | 百万级就很慢 |
| 相关性 | 自动评分排序 | 无 |
Q2: 分词器是什么?
答案:
分词器将文本切分为词条(Term)。如「React 性能优化」:
- 标准分词器:
react、性、能、优、化(按字切分) - IK 分词器(中文):
react、性能、优化(按语义切分)
Q3: ES 如何保证和数据库的数据一致?
答案:
- 双写:写数据库的同时写 ES(有一致性风险)
- CDC(Change Data Capture):监听 MySQL Binlog 同步到 ES(推荐)
- 消息队列:写数据库后发消息,消费者写 ES
相关链接
- 设计搜索自动补全系统 - 搜索系统设计
- 向量数据库 - 语义搜索