跳到主要内容

第4章 Elasticsearch数据操作

3.1 数据格式与概念

ES 与 MySQL 概念对比

理解 Elasticsearch 的数据组织方式:

MySQLElasticsearch说明
数据库索引 (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 进行精确匹配
  • 合理使用 sizefrom 参数分页
  • 避免查询大量数据时使用 match_all
  • 根据业务需求选择合适的分词器

3.8 小结

本章学习了 Elasticsearch 的核心数据操作:

  • 数据格式:理解 JSON 文档结构和与关系数据库的对应关系
  • 文档创建:掌握自定义 ID 和自动生成 ID 的使用场景
  • 查询操作:从简单查询到复杂的多条件组合查询
  • 更新删除:全量更新、部分更新和安全删除的正确方式
  • 索引管理:创建、查看、删除索引的基本操作
  • 故障排除:常见问题的诊断和解决方法
📖 下节预告

下一章将学习 Elasticsearch 的集群部署和运维管理,从单机环境扩展到生产级集群。


📝 文档更新时间:2025-01-26
🔄 版本信息:适用于 Elasticsearch 7.x-8.x 系列
🎯 实践建议:建议在测试环境多练习各种操作,熟悉后再应用到生产环境