当前位置: 首页 > article >正文

Elasticsearch如何删除字段

文章目录

  • 1、问题描述
  • 2、案例讲解
  • 3、问题剖析
  • 4、解决方案
    • 4.1 注意:
    • 4.2 步骤:
    • 4.3 示例:
      • 4.3.1 创建一个新的索引
      • 4.3.2 reindex 重建索引
      • 4.3.3 恢复索引
  • 5、彩蛋 & 坑
    • 5.1 坑
    • 5.2 使用 Pipline
  • 6、总结

1、问题描述

在 Elasticsearch 中,删除字段是一个常见的需求,尤其是在数据模型发生变化或需要清理无用字段时。

以下是一些常见的需要删除字段的场景:

  • 数据模型变更:某些字段不再需要,需要从索引中移除。
  • 数据清理:删除敏感信息或无用的字段。
  • 性能优化:减少索引的大小,提升查询性能。
  • 修改类型:由于字段类型前期预估错误,需要删除重建

传统的 SQL 数据库可以直接使用 ALTER TABLE DROP COLUMN,但在 Elasticsearch 中,删除字段可能并不是想象的那么简单,Elasticsearch 并没有直接提供删除字段的 API,而是需要通过一些间接的方式来实现。本文将详细介绍如何在 Elasticsearch 中删除字段,包括使用场景、解决方案和实际案例。

2、案例讲解

假设有一个索引 my_index,其中包含字段 t1t2,现在需要删除 t1

首先写入测试索引字段类型可以使用自动映射

POST /my_index/_doc
{
  "t1": "我是我是第一个字段",
  "t2": "我是第二个字段"
}

查询结果记录

GET my_index/_search

在这里插入图片描述
尝试使用 _update 结合 script 删除字段

POST my_index/_update/RakddJUBPtRg8Gmh8sq8
{
  "script": "ctx._source.remove('t1')"
}

当然,你也可以使用 update_by_query 对文档进行批量操作:

POST my_index/_update_by_query
{
  "query": {
    "match_all": {}
  },
  "script": "ctx._source.remove('t1')"
}

执行完毕之后,在此查询结果,发现的确删掉了 t1 字段

在这里插入图片描述

3、问题剖析

看似达到了效果,但是,字段真的删掉了吗?

ES 的特性不同于 RDB,是允许稀疏字段存在的,可以是 doc1: field1,field2;doc2:field2,field3。这种情况是允许的,也就是说,查不到结果,不一定就意味着字段不存在。

查看索引的映射,验证一下:

GET my_index/_mapping

在这里插入图片描述
果然,字段 t1 依旧还是存在的,只不过所查询的文档记录,t1 并没有值,所以也就看不到。

4、解决方案

Elasticsearch 的索引映射(mapping)一旦创建,字段的类型和结构就不能直接修改。如果需要删除某个字段,

重建索引是 Elasticsearch 中删除字段的最常见方法。通过创建一个新的索引,并将旧索引的数据复制到新索引中(排除需要删除的字段),可以实现字段的删除。

4.1 注意:

删除字段需要借助以下方法:

  • 重建索引(Reindex)。
  • 使用 _update_by_query 更新文档。
  • 使用 Ingest Pipeline 过滤字段。

4.2 步骤:

  1. 创建一个新的索引,定义新的映射(不包含需要删除的字段)。
  2. 使用 _reindex API 将旧索引的数据复制到新索引中。
  3. 删除旧索引,将新索引重命名为旧索引的名称(可选)。

4.3 示例:

4.3.1 创建一个新的索引

如果源索引的名字可以修改,可以把新索引作为源索引的替代,不然的话,后面需要将新索引重新再 reindex 回去,一共需要 reindex 两次

PUT /my_index_bak
{
  "mappings": {
    "properties": {
      "t2": {
        "type": "text"
      }
    }
  }
}

注意,字段 t2 如果需要和源索引类型保持一致,直接复制源索引的字段类型即可,这里删除 t1 的字段映射。

4.3.2 reindex 重建索引

POST /_reindex
{
  "source": {
    "index": "my_index"
  },
  "dest": {
    "index": "my_index_bak"
  },
  "script": {
    "source": "ctx._source.remove('t1')"
  }
}

再次查看索引 mapping,可以看到,字段 t1 就已经被彻底删除了

4.3.3 恢复索引

当新索引创建完成,旧索引就可以删除了,然后同样的方式,把新索引的 mapping 重新创建一次,使用需要的索引名称即可

POST /_reindex
{
  "source": {
    "index": "my_index_bak"
  },
  "dest": {
    "index": "my_index"
  }
}

再次查看索引 mapping,可以看到,字段 t1 就已经被彻底删除了

或者给新索引添加别名

DELETE /my_index
PUT /my_index_bak/_alias/my_index

5、彩蛋 & 坑

5.1 坑

在执行重建索引的时候,有一个关键操作

  "script": {
    "source": "ctx._source.remove('t1')"
  }

它的意思是在重建索引时,会删除指定的字段,比如上面代码在重建的时候,就会忽略 t1 字段,这样新索引就不会有 t1 字段,不然,即便新索引没有创建 t1 字段的 mapping,也会因为源索引包含 t1 字段且会因为 dynamic mapping 而导致 t1 重新被写入。

因此,这一步是绝对不能忽视的。

5.2 使用 Pipline

在 reindex 的时候,也可以通过 Pipeline 来达到同样的目的

PUT _ingest/pipeline/remove_t1
{
  "processors": [
    {
      "remove": {
        "field": "t1"
      }
    }
  ]
}
# 重建索引
POST /_reindex?
{
  "source": {
    "index": "my_index"
  },
  "dest": {
    "index": "my_index_bak",
    "pipeline": "remove_t1"
  }
}

6、总结

  • Elasticsearch 索引具备不可变性,字段的类型是不可修改的,包括删除字段,因此一切通过修改当前索引的操作都是不可行的,包括:
    • update API
    • update_by_query API
  • 重建索引可以通过 Script 或者 Pipline 完成过滤字段,但是后者需要创建 pipline,因此更推荐前者

http://www.kler.cn/a/579526.html

相关文章:

  • Linux系统基于ARM平台的LVGL移植
  • clickhouse 频繁刷新
  • 算法与数据结构(最长回文子串)
  • PTA L2一些题目
  • 学习网络安全需要哪些基础?
  • ubuntu直接安装mobaxterm
  • 大模型最新面试题系列:训练篇之模型监控与调试
  • CarPlanner:用于自动驾驶大规模强化学习的一致性自回归轨迹规划
  • 串口助手的C#编写以及有人串口服务器USR-DR301的使用
  • 《用Python+PyGame开发双人生存游戏!源码解析+完整开发思路分享》
  • QT——对象树
  • 数据分析和可视化课程实验报告一(数据分析基础)
  • 如何通過安裝輕量性圖形界面減少Linux服務器壓力
  • c#面试题整理7
  • 利用pdf.js+百度翻译实现PDF翻译,创建中文PDF
  • SpringBoot 自定义异常处理
  • SparkAi系统体验
  • 【最后203篇系列】011 Mongo异步代理开发回顾
  • golang 从零单排 (一) 安装环境
  • 京东POP商家小程序电商布局策略与优化路径研究