Elasticsearch如何删除字段

ops/2025/3/10 20:38:11/

文章目录

  • 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.ppmy.cn/ops/164749.html

相关文章

uniApp实战二:仿今日相机水印功能

文章目录 1.最终效果预览2.页面实现 1.最终效果预览 2.页面实现 页面布局 <view click"handleTakePhotoNew">拍照</view><view v-if"!snapSrc"><canvas canvas-id"canvas" :style"{width:cvWidthpx,height:cvHeight…

利用可变参数模板,可打印任意参数和参数值。(C++很好的调式函数)

很酷的应用&#xff1a; &#xff08;1&#xff09; 如何获取可变参数名 代码例子&#xff1a; #define _test(...) (test_t(#__VA_ARGS__, __VA_ARGS__))template<typename... Args> void test_t(const char* names, Args... args) {std::cout << names <<…

C++20 中使用括号进行聚合初始化:新特性与实践指南

文章目录 1. 聚合初始化简介2. C20 中的括号聚合初始化2.1 指定初始化器&#xff08;Designated Initializers&#xff09;2.2 嵌套聚合初始化 3. 使用括号初始化数组4. 注意事项5. 实际应用场景6. 总结 在 C20 中&#xff0c;聚合初始化&#xff08;Aggregate Initialization&…

AI视频生成工具清单(附网址与免费说明)

以下是一份详细的AI视频制作网站总结清单&#xff0c;包含免费/付费信息及核心功能说明&#xff1a; AI视频生成工具清单&#xff08;附网址与免费说明&#xff09; 1. Synthesia 网址&#xff1a;https://www.synthesia.io是否免费&#xff1a;免费试用&#xff08;生成视频…

在Dify中访问Gemini等模型代理设置指南

问题背景 Google Gemini模型可纯免费使用&#xff0c;且性能也相当不错&#xff0c;一般个人使用或研究足够。但在在国内访问&#xff0c;需设置代理。在Docker部署Dify时&#xff0c;虽然按官方文档介绍设置代理环境变量&#xff0c;但实测发现并不生效。我们通过研究试验解决…

【Git】linux搭建Gitea配置mysql数据库

WindowsServer搭建内网Gitea【中文更方便使用】 1. 安装Gitea # 下载 wget https://dl.gitea.io/gitea/1.23.5/gitea-1.23.5-linux-amd642. 创建用户 # 创建 gitea 用户&#xff1a;这个命令的作用是创建一个名为 git 的系统用户&#xff0c;该用户使用 /bin/bash 作为默认 …

课题推荐——无人机在UWB环境下基于TOA/TDOA/AOA的室内定位与精度对比

随着无人机在工业检测、仓储物流、应急救援等室内场景的广泛应用&#xff0c;高精度室内定位技术成为关键支撑。超宽带&#xff08;UWB&#xff09;技术凭借其高时间分辨率、强抗多径能力等优势&#xff0c;成为室内定位的主流方案。然而&#xff0c;不同的定位方法&#xff08…

可狱可囚的爬虫系列课程 19:静态页面和动态页面之分

在爬虫开发中&#xff0c;静态页面和动态页面的核心区别在于数据的生成和加载方式&#xff0c;理解两者的差异直接影响爬虫技术选型和数据抓取策略&#xff1b;掌握静态/动态页面的区别&#xff0c;可显著提升爬虫效率和成功率。 一、静态页面&#xff08;Static Page&#xf…