第4章 Elasticsearch数据操作
3.1 数据格式与概念
ES 与 MySQL 概念对比
理解 Elasticsearch 的数据组织方式:
MySQL | Elasticsearch | 说明 |
---|---|---|
数据库 | 索引 (Index) | 数据的逻辑分组 |
表 | 类型 (_doc) | 数据结构定义 |
字段 | JSON 的 Key | 数据属性名称 |
值 | JSON 的 Value | 数据属性值 |
行 | 文档 (Document) | 一条完整记录 |
JSON 文档结构
Elasticsearch 使用 JSON 格式存储数据:
{
"name": "张三",
"age": 29,
"address": "北京",
"job": "工程师"
}
💡 数据格式提示
- 所有数据都以 JSON 文档形式存储
- 字段可以是字符串、数字、布尔值、数组或嵌套对象
- 无需预定义 schema,支持动态字段
3.2 文档创建操作
使用自定义 ID 创建文档
当需要指定文档 ID 时使用 PUT 方法:
命令行方式:
curl -XPUT 'http://localhost:9200/users/_doc/1' \
-H 'Content-Type: application/json' \
-d '{
"name": "张三",
"age": 29,
"job": "工程师"
}'
Kibana 控制台方式:
PUT users/_doc/1
{
"name": "张三",
"age": 29,
"job": "工程师"
}
使用自动生成 ID
当不需要指定 ID 时使用 POST 方法:
POST users/_doc/
{
"name": "李四",
"age": 25,
"address": "上海",
"job": "设计师"
}
Elasticsearch 会自动生成类似 CVDdknIBq3aq7mPQaoWw
的随机 ID。
批量插入测试数据
为后续查询演示创建多条测试数据:
POST users/_doc/
{
"name": "王五",
"age": 30,
"address": "北京",
"job": "开发工程师"
}
POST users/_doc/
{
"name": "赵六",
"age": 24,
"address": "深圳",
"job": "产品经理"
}
POST users/_doc/
{
"name": "钱七",
"age": 35,
"address": "广州",
"job": "运维工程师"
}
💡 最佳实践
ID 使用建议:
- 自定义 ID:适用于需要与外部系统关联的场景
- 自动 ID:适用于纯 ES 内部使用的场景
- 业务 ID 映射:可在文档中保留原始业务 ID 字段
3.3 文档查询操作
查询所有文档
最基本的查询操作:
GET users/_search
该命令返回索引中的所有文档(默认返回10条)。
精确查询
使用 term
查询进行精确匹配:
# 根据姓名查询
GET users/_search
{
"query": {
"term": {
"name.keyword": "张三"
}
}
}
# 根据职业查询
GET users/_search
{
"query": {
"term": {
"job.keyword": "工程师"
}
}
}
多条件查询
使用 bool
查询组合多个条件:
GET users/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"job.keyword": "工程师"
}
},
{
"term": {
"address.keyword": "北京"
}
},
{
"range": {
"age": {
"gte": 25,
"lte": 35
}
}
}
]
}
}
}
常用查询类型
范围查询:
GET users/_search
{
"query": {
"range": {
"age": {
"gte": 25,
"lt": 30
}
}
}
}
模糊查询:
GET users/_search
{
"query": {
"match": {
"name": "张"
}
}
}
⚠️ 查询注意事项
字段类型说明:
name
- 进行分词,适合模糊查询name.keyword
- 不分词,适合精确查询- 数字字段可直接使用,无需
.keyword
后缀
3.4 文档更新操作
全量更新(覆盖)
使用 PUT 完全替换文档内容:
PUT users/_doc/1
{
"name": "张三",
"age": 30,
"address": "北京",
"job": "高级工程师",
"department": "技术部"
}
部分更新
使用 POST 和 _update
只更新指定字段:
POST users/_update/1
{
"doc": {
"age": 31,
"job": "技术主管"
}
}
根据查询条件更新
先查询获取文档 ID,再进行更新:
步骤1:查询文档
GET users/_search
{
"query": {
"term": {
"name.keyword": "李四"
}
}
}
步骤2:使用返回的 ID 更新
PUT users/_doc/返回的_id
{
"name": "李四",
"age": 26,
"address": "上海",
"job": "高级设计师"
}
🚨 更新操作风险
重要提醒:
- 全量更新会覆盖整个文档,未指定的字段将被删除
- 部分更新更安全,只修改指定字段
- 更新前建议先备份重要数据
- 生产环境慎用批量更新操作
3.5 文档删除操作
删除单个文档
DELETE users/_doc/1
根据查询条件删除
POST users/_delete_by_query
{
"query": {
"term": {
"job.keyword": "已离职"
}
}
}
🚨 删除操作警告
数据删除风险:
- 删除操作不可逆,请确保已备份重要数据
- 批量删除前先测试查询条件是否正确
- 生产环境删除需要审批流程
- 建议先查询确认要删除的数据范围
3.6 索引管理
创建索引
PUT products
{
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"price": {
"type": "double"
},
"create_time": {
"type": "date"
}
}
}
}
查看索引信息
# 查看所有索引
GET _cat/indices
# 查看索引映射
GET users/_mapping
# 查看索引设置
GET users/_settings
删除索引
DELETE users
🚨 索引删除严重警告
极高风险操作:
- 删除索引会丢失所有数据,且无法恢复
- 生产环境禁止随意删除索引
- 删除前必须确认数据已完整备份
- 建议使用索引别名来避免误删除
3.7 实用技巧与故障排除
常用运维命令
查看集群健康状态:
GET _cluster/health
查看节点信息:
GET _cat/nodes?v
查看索引统计:
GET _cat/indices?v&s=store.size:desc
常见问题处理
⚠️ 查询结果为空
可能原因:
- 字段名称拼写错误
- 查询语法不正确
- 数据类型不匹配(如对 text 字段进行 term 查询)
解决方法:
# 检查索引结构
GET users/_mapping
# 验证数据是否存在
GET users/_search
{
"query": {
"match_all": {}
}
}
💡 查询优化技巧
提升查询性能:
- 使用
term
查询代替match
进行精确匹配 - 合理使用
size
和from
参数分页 - 避免查询大量数据时使用
match_all
- 根据业务需求选择合适的分词器
3.8 小结
本章学习了 Elasticsearch 的核心数据操作:
- 数据格式:理解 JSON 文档结构和与关系数据库的对应关系
- 文档创建:掌握自定义 ID 和自动生成 ID 的使用场景
- 查询操作:从简单查询到复杂的多条件组合查询
- 更新删除:全量更新、部分更新和安全删除的正确方式
- 索引管理:创建、查看、删除索引的基本操作
- 故障排除:常见问题的诊断和解决方法
📖 下节预告
下一章将学习 Elasticsearch 的集群部署和运维管理,从单机环境扩展到生产级集群。
📝 文档更新时间:2025-01-26
🔄 版本信息:适用于 Elasticsearch 7.x-8.x 系列
🎯 实践建议:建议在测试环境多练习各种操作,熟悉后再应用到生产环境