Elasticsearch
欢迎来到 Elasticsearch 知识库!
🔍 Elasticsearch 简介
Elasticsearch (ES) 是一个基于 Lucene 的分布式搜索和分析引擎,能够实现近实时的搜索、分析大规模数据。广泛应用于全文搜索、日志分析、数据可视化等场景。
🎯 核心特性
✅ 主要优势
- 分布式 - 天然支持集群,自动分片和复制
- 近实时 - 数据写入后约 1 秒可搜索
- 全文搜索 - 强大的文本分析和搜索能力
- RESTful API - 简单易用的 HTTP 接口
- 多租户 - 支持多索引查询
- 文档导向 - 以 JSON 文档存储数据
📊 ES vs 传统数据库
| 概念 | Elasticsearch | MySQL |
|---|---|---|
| 数据库 | Index (索引) | Database |
| 表 | Type (类型, 7.x 已废弃) | Table |
| 行 | Document (文档) | Row |
| 列 | Field (字段) | Column |
| Schema | Mapping (映射) | Schema |
🎯 适用场景
✅ 特别适合
- 全文搜索 - 电商搜索、站内搜索
- 日志分析 - ELK 日志收集分析
- 数据分析 - 实时统计、聚合分析
- APM - 应用性能监控
- 安全分析 - 日志审计、威胁检测
⚠️ 不太适合
- 主数据库(不支持事务)
- 频繁更新的数据
- 复杂的关联查询
🚀 快速开始
1. 基本概念
集群 (Cluster)
└─ 节点 (Node)
└─ 索引 (Index)
└─ 分片 (Shard)
├─ 主分片 (Primary Shard)
└─ 副本分片 (Replica Shard)2. 索引操作
bash
# 创建索引
PUT /users
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"username": { "type": "keyword" },
"email": { "type": "keyword" },
"age": { "type": "integer" },
"bio": { "type": "text" },
"createdAt": { "type": "date" }
}
}
}
# 查看索引
GET /users
# 删除索引
DELETE /users3. 文档操作 (CRUD)
bash
# 创建文档 (指定 ID)
PUT /users/_doc/1
{
"username": "zhangsan",
"email": "zhang@example.com",
"age": 25,
"bio": "热爱技术的程序员",
"createdAt": "2024-01-01T12:00:00Z"
}
# 创建文档 (自动生成 ID)
POST /users/_doc
{
"username": "lisi",
"email": "li@example.com",
"age": 30
}
# 查询文档
GET /users/_doc/1
# 更新文档 (部分更新)
POST /users/_update/1
{
"doc": {
"age": 26
}
}
# 删除文档
DELETE /users/_doc/1🔍 搜索查询
1. 简单查询
bash
# 查询所有文档
GET /users/_search
{
"query": {
"match_all": {}
}
}
# 精确匹配
GET /users/_search
{
"query": {
"term": {
"username": "zhangsan"
}
}
}
# 全文搜索
GET /users/_search
{
"query": {
"match": {
"bio": "程序员"
}
}
}
# 多字段搜索
GET /users/_search
{
"query": {
"multi_match": {
"query": "张三",
"fields": ["username", "bio"]
}
}
}2. 复合查询
bash
# bool 查询
GET /users/_search
{
"query": {
"bool": {
"must": [
{ "match": { "bio": "程序员" } }
],
"filter": [
{ "range": { "age": { "gte": 20, "lte": 30 } } }
],
"should": [
{ "term": { "username": "zhangsan" } }
],
"must_not": [
{ "term": { "status": "deleted" } }
]
}
}
}bool 查询子句:
- must - 必须匹配,影响相关性得分
- filter - 必须匹配,不影响得分(可缓存)
- should - 应该匹配,影响得分
- must_not - 必须不匹配,不影响得分
3. 范围查询
bash
GET /users/_search
{
"query": {
"range": {
"age": {
"gte": 20,
"lte": 30
}
}
}
}
# 日期范围
GET /users/_search
{
"query": {
"range": {
"createdAt": {
"gte": "2024-01-01",
"lt": "2024-12-31"
}
}
}
}4. 模糊查询
bash
# 前缀查询
GET /users/_search
{
"query": {
"prefix": {
"username": "zhan"
}
}
}
# 通配符查询
GET /users/_search
{
"query": {
"wildcard": {
"username": "zhan*"
}
}
}
# 模糊查询
GET /users/_search
{
"query": {
"fuzzy": {
"username": {
"value": "zhangsan",
"fuzziness": 2
}
}
}
}📊 聚合分析
1. Metrics 聚合(指标)
bash
# 平均值
GET /users/_search
{
"size": 0,
"aggs": {
"avg_age": {
"avg": { "field": "age" }
}
}
}
# 多个统计
GET /users/_search
{
"size": 0,
"aggs": {
"stats_age": {
"stats": { "field": "age" }
}
}
}2. Bucket 聚合(分组)
bash
# 按字段分组
GET /users/_search
{
"size": 0,
"aggs": {
"group_by_age": {
"terms": {
"field": "age",
"size": 10
}
}
}
}
# 范围分组
GET /users/_search
{
"size": 0,
"aggs": {
"age_ranges": {
"range": {
"field": "age",
"ranges": [
{ "to": 20 },
{ "from": 20, "to": 30 },
{ "from": 30 }
]
}
}
}
}
# 日期直方图
GET /users/_search
{
"size": 0,
"aggs": {
"users_over_time": {
"date_histogram": {
"field": "createdAt",
"calendar_interval": "month"
}
}
}
}3. 嵌套聚合
bash
GET /users/_search
{
"size": 0,
"aggs": {
"group_by_age": {
"terms": { "field": "age" },
"aggs": {
"avg_score": {
"avg": { "field": "score" }
}
}
}
}
}🔧 Mapping 映射
数据类型
核心类型
bash
{
"mappings": {
"properties": {
# 字符串
"title": { "type": "text" }, # 全文搜索
"status": { "type": "keyword" }, # 精确匹配
# 数字
"age": { "type": "integer" },
"price": { "type": "float" },
# 日期
"createdAt": { "type": "date" },
# 布尔
"isActive": { "type": "boolean" },
# 对象
"user": {
"properties": {
"name": { "type": "keyword" },
"age": { "type": "integer" }
}
},
# 数组 (自动推断类型)
"tags": { "type": "keyword" }
}
}
}text vs keyword
| 特性 | text | keyword |
|---|---|---|
| 分词 | ✅ 分词 | ❌ 不分词 |
| 全文搜索 | ✅ | ❌ |
| 精确匹配 | ❌ | ✅ |
| 排序 | ❌ | ✅ |
| 聚合 | ❌ | ✅ |
🔍 中文分词
IK 分词器
bash
# 安装
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.10.0/elasticsearch-analysis-ik-7.10.0.zip
# 创建索引时指定分词器
PUT /articles
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word", # 索引时使用
"search_analyzer": "ik_smart" # 搜索时使用
}
}
}
}ik_max_word: 最细粒度拆分
"中华人民共和国" -> "中华人民共和国", "中华人民", "中华", "华人", "人民共和国", "人民", "共和国", "共和", "国"ik_smart: 最粗粒度拆分
"中华人民共和国" -> "中华人民共和国"📈 性能优化
1. 索引优化
bash
# 批量索引
POST /_bulk
{"index":{"_index":"users","_id":"1"}}
{"username":"user1","age":25}
{"index":{"_index":"users","_id":"2"}}
{"username":"user2","age":30}
# 调整刷新间隔
PUT /users/_settings
{
"index": {
"refresh_interval": "30s" # 默认 1s
}
}2. 查询优化
bash
# 使用 filter 而非 query(可缓存)
GET /users/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "status": "active" } }
]
}
}
}
# 限制返回字段
GET /users/_search
{
"_source": ["username", "email"],
"query": { "match_all": {} }
}3. 分页
bash
# from + size (浅分页)
GET /users/_search
{
"from": 0,
"size": 20,
"query": { "match_all": {} }
}
# search_after (深分页)
GET /users/_search
{
"size": 20,
"query": { "match_all": {} },
"search_after": [1234, "abc"], # 上一页最后一条记录的 sort 值
"sort": [
{ "_id": "asc" }
]
}🔗 Node.js 客户端
javascript
const { Client } = require('@elastic/elasticsearch');
const client = new Client({
node: 'http://localhost:9200'
});
// 创建文档
await client.index({
index: 'users',
id: '1',
document: {
username: 'zhangsan',
email: 'zhang@example.com',
age: 25
}
});
// 搜索
const result = await client.search({
index: 'users',
query: {
match: {
username: 'zhangsan'
}
}
});
console.log(result.hits.hits);
// 聚合
const aggResult = await client.search({
index: 'users',
size: 0,
aggs: {
avg_age: {
avg: { field: 'age' }
}
}
});
console.log(aggResult.aggregations.avg_age.value);💡 最佳实践
合理设计 Mapping
- 选择正确的字段类型
- text 用于全文搜索,keyword 用于精确匹配
- 不需要搜索的字段设置
"index": false
使用 filter 而非 query
- filter 可以缓存,性能更好
- 不需要评分时使用 filter
批量操作
- 使用 Bulk API 批量索引
- 减少网络开销
控制文档大小
- 避免过大的文档
- 单个文档不超过几 MB
合理设置副本和分片
- 主分片数创建后不可修改
- 副本数可以动态调整
📖 学习资源
官方资源
推荐书籍
- 《Elasticsearch 权威指南》
- 《Elasticsearch 实战》
ELK Stack
- Elasticsearch - 搜索和分析引擎
- Logstash - 数据收集和处理
- Kibana - 数据可视化
准备好了吗?开始你的 Elasticsearch 学习之旅!