第三章:核心概念
深入理解 Elasticsearch 的核心概念,包括索引、文档、映射、分片、副本等。
最后更新: 2024-01-15
页面目录
第三章:核心概念
3.1 索引(Index)
索引是 Elasticsearch 中存储文档的逻辑容器,用于组织和管理具有相似特征的文档。
3.1.1 索引命名规范
- 只能是小写字母
- 可以包含数字和
-、_字符 - 不能以
-、_、+开头 - 长度不能超过 255 个字符
- 不能使用
.开头(保留给内部使用)
3.1.2 索引配置
PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "1s"
},
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "float" },
"category": { "type": "keyword" },
"created_at": { "type": "date" }
}
}
}
3.2 文档(Document)
文档是 Elasticsearch 中的基本数据单元,以 JSON 格式存储。
3.2.1 文档结构
{
"_index": "products",
"_id": "1",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"_source": {
"name": "iPhone 15 Pro",
"brand": "Apple",
"price": 9999.00,
"category": "smartphone",
"tags": ["5G", "旗舰", "拍照"],
"specs": {
"screen": "6.1英寸",
"storage": "256GB",
"battery": "4000mAh"
},
"stock": 100,
"is_active": true,
"created_at": "2024-01-15T10:30:00Z"
}
}
3.2.2 文档元字段
| 字段 | 说明 |
|---|---|
_index |
文档所属的索引 |
_id |
文档唯一标识 |
_version |
文档版本号 |
_seq_no |
操作序列号 |
_primary_term |
主分片任期号 |
_source |
文档原始内容 |
3.3 映射(Mapping)
映射定义了索引中文档的字段结构和类型。
3.3.1 字段数据类型
核心类型
| 类型 | 说明 | 示例 |
|---|---|---|
text |
文本类型,会分词 | 文章内容 |
keyword |
关键词,不分词 | 标签、状态 |
long |
64位整数 | 数量 |
integer |
32位整数 | 整数字段 |
short |
16位整数 | 小整数 |
byte |
8位整数 | -128~127 |
double |
64位浮点 | 双精度 |
float |
32位浮点 | 单精度 |
half_float |
16位浮点 | 半精度 |
scaled_float |
缩放浮点 | 价格 |
boolean |
布尔值 | true/false |
binary |
二进制 | Base64编码 |
date |
日期 | 时间戳 |
复杂类型
| 类型 | 说明 |
|---|---|
object |
JSON 对象 |
nested |
嵌套文档 |
array |
数组 |
特殊类型
| 类型 | 说明 |
|---|---|
ip |
IPv4/IPv6 地址 |
geo_point |
地理位置 |
geo_shape |
地理形状 |
completion |
自动补全 |
murmur3 |
哈希值 |
token_count |
分词计数 |
3.3.2 映射示例
PUT /blog
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
},
"author": {
"type": "object",
"properties": {
"name": { "type": "keyword" },
"email": { "type": "keyword" },
"age": { "type": "integer" }
}
},
"tags": {
"type": "keyword"
},
"views": {
"type": "long"
},
"published": {
"type": "boolean"
},
"published_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"location": {
"type": "geo_point"
}
}
}
}
3.3.3 动态映射
Elasticsearch 自动推断字段类型:
| JSON 数据 | 推断类型 |
|---|---|
"string" |
text + keyword |
123 |
long |
123.45 |
double |
true/false |
boolean |
"2024-01-01" |
date |
[1, 2, 3] |
long array |
{"key": "value"} |
object |
3.4 分片(Shard)
分片是索引的水平拆分单元,每个分片是一个独立的 Lucene 索引。
3.4.1 主分片与副本分片
┌─────────────────────────────────────────────────────────────┐
│ Index │
│ (Primary Shards: 3, Replicas: 1) │
├───────────────────┬───────────────────┬─────────────────────┤
│ Primary 0 │ Primary 1 │ Primary 2 │
│ ┌─────────┐ │ ┌─────────┐ │ ┌─────────┐ │
│ │ Shard 0 │ │ │ Shard 1 │ │ │ Shard 2 │ │
│ └─────────┘ │ └─────────┘ │ └─────────┘ │
│ ┌─────────┐ │ ┌─────────┐ │ ┌─────────┐ │
│ │Replica 0│ │ │Replica 1│ │ │Replica 2│ │
│ └─────────┘ │ └─────────┘ │ └─────────┘ │
│ Node 1 │ Node 2 │ Node 3 │
└───────────────────┴───────────────────┴─────────────────────┘
3.4.2 分片策略
| 策略 | 说明 | 建议 |
|---|---|---|
| 分片数量 | 索引创建后不可更改 | 根据数据量评估 |
| 副本数量 | 可随时调整 | 至少 1 |
| 分片大小 | 建议 30-50GB | 避免过大或过小 |
3.4.3 分片分配规则
- 同一分片的副本不会在同一节点
- 新索引默认 1 个副本
- 零副本索引只有主分片
3.5 节点(Node)
3.5.1 节点类型
| 类型 | 配置 | 职责 |
|---|---|---|
| Master | node.master: true |
集群管理 |
| Data | node.data: true |
数据存储 |
| Ingest | node.ingest: true |
文档预处理 |
| Coordinating | 所有 false |
请求路由 |
3.5.2 节点配置
# Master 节点
node.master: true
node.data: false
node.ingest: false
# Data 节点
node.master: false
node.data: true
node.ingest: false
# Coordinating 节点
node.master: false
node.data: false
node.ingest: false
# 专用 Ingest 节点
node.ingest: true
pipeline.workers: 3
pipeline.batch_size: 200
3.5.3 节点属性
node.attr.rack: rack1
node.attr.zone: us-east-1a
node.attr.size: medium
3.6 集群(Cluster)
3.6.1 集群状态
GET /_cluster/health
{
"cluster_name": "production-es",
"status": "green",
"timed_out": false,
"number_of_nodes": 3,
"number_of_data_nodes": 3,
"active_primary_shards": 45,
"active_shards": 90,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}
| 状态 | 含义 |
|---|---|
green |
所有分片正常 |
yellow |
所有主分片正常,副本未分配 |
red |
存在未分配的主分片 |
3.6.2 集群状态详解
Green (健康)
┌─────┐ ┌─────┐ ┌─────┐
│ P0 │ │ P1 │ │ P2 │ Primary Shards (全部在线)
├─────┤ ├─────┤ ├─────┤
│ R0 │ │ R1 │ │ R2 │ Replica Shards (全部在线)
└─────┘ └─────┘ └─────┘
Yellow (亚健康)
┌─────┐ ┌─────┐ ┌─────┐
│ P0 │ │ P1 │ │ P2 │ Primary Shards (全部在线)
├─────┤ ├─────┤ ├─────┤
│ R0 │ │ R1 │ │ R2 │ Replica Shards (部分缺失)
└─────┘ └─────┘ └─────┘
✗
Red (不健康)
┌─────┐ ┌─────┐ ┌─────┐
│ P0 │ │ P1 │ │ P2 │ Primary Shards (部分丢失)
├─────┤ ├─────┤ ├─────┤
│ R0 │ │ R1 │ │ R2 │
└─────┘ └─────┘ └─────┘
✗
3.7 倒排索引
倒排索引是 Elasticsearch 实现全文搜索的核心数据结构。
3.7.1 索引结构
文档列表:
Doc1: "The quick brown fox"
Doc2: "Quick brown foxes"
Doc3: "The brown fox leaps"
倒排索引:
┌──────────┬──────────────────────┐
│ Term │ Posting List │
├──────────┼──────────────────────┤
│ brown │ [Doc1, Doc2, Doc3] │
│ fox │ [Doc1, Doc3] │
│ foxes │ [Doc2] │
│ leaps │ [Doc3] │
│ quick │ [Doc1, Doc2] │
│ the │ [Doc1, Doc3] │
└──────────┴──────────────────────┘
3.7.2 分词与标准化
POST _analyze
{
"analyzer": "standard",
"text": "Quick Brown Foxes!"
}
响应:
{
"tokens": [
{ "token": "quick", "start_offset": 0, "end_offset": 5 },
{ "token": "brown", "start_offset": 6, "end_offset": 11 },
{ "token": "fox", "start_offset": 12, "end_offset": 15 },
{ "token": "fox", "start_offset": 16, "end_offset": 21 }
]
}
3.8 文档生命周期
3.8.1 CRUD 操作
# 创建文档
PUT /products/_doc/1
{
"name": "iPhone 15",
"price": 7999.00,
"category": "electronics"
}
# 读取文档
GET /products/_doc/1
# 更新文档
POST /products/_update/1
{
"doc": {
"price": 7499.00
}
}
# 删除文档
DELETE /products/_doc/1
# 批量操作
POST /_bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "name": "Product 1" }
{ "delete": { "_index": "products", "_id": "2" } }
3.9 总结
本章深入介绍了 Elasticsearch 的核心概念,包括索引、文档、映射、分片和集群等。理解这些概念对于后续的学习和实践至关重要。下一章将学习索引的管理操作。