Elasticsearch 8.X 如何优雅的实现字段名称批量修改?

这篇具有很好参考价值的文章主要介绍了Elasticsearch 8.X 如何优雅的实现字段名称批量修改?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、线上实战问题

写入es前,数据格式如下

{"json_lbm_01":"test01","json_lbm_02":"test02","tmp_lbm_01":"test03","tmp_lbm_02":"test04"}

需求:单纯用pipeline可不可以实现,如果写入key包含json_提换为空,包含tmp提换为core,因为key字段有很多不考虑穷举,最终效果要如下:

{
  "lbm_01":"test01",
  "lbm_02":"test02",
  "core_lbm_01":"test03",
  "core_lbm_02":"test04"
}

——问题来源:死磕Elasticsearch知识星球 https://t.zsxq.com/0bzWL3w1X

2、认知前提

Elasticsearch mapping 一旦创建是不允许修改的!允许更新 mapping 的地方是几个特殊的点,可以参见:Elasticsearch 可以更改 Mapping 吗?如何修改?

除此之外的 mapping 层面尤其字段层面想要修改需要转换思路。

3、Mapping 字段非要修改,以满足业务需求怎么搞?

看开篇问题,本质上属于建模问题,应该建模阶段处理好,后期就不存在这个问题,这点期望大家可以达成共识。

关于Elasticsearch 数据建模的重要性,推荐参考:

干货 | Elasticsearch 数据建模指南

针对开篇问题,考虑如下的解决方案:

3.1 方案一,字段别名实现。

字段别名 field-alias 区别于索引别名 alias。

索引别名大家都比较熟悉,字段别名听到的多,但是实际用的不见得有那么多。

字段别名是 Elasticsearch 6.4 版本新上的功能,具体参见:

https://www.elastic.co/cn/blog/introducing-field-aliases-in-elasticsearch

因为一般前期建模做足功课,后面环节就不需要了。

  • 优点:已有mapping保持不动,只是在其基础上做了更新操作。

  • 缺点:批量1000个字 段,需要构造1000个字段的mapping,其实可以 脚本实现。

实操参考:

POST mytxindex-20230303/_bulk
{"index":{"_id":1}}
{"json_lbm_01":"test01","json_lbm_02":"test02","tmp_lbm_01":"test03","tmp_lbm_02":"test04"}


PUT mytxindex-20230303/_mapping
{
    "properties": {
      "lbm_01": {
        "type": "alias",
        "path": "json_lbm_01"
      },
      "lbm_02": {
        "type": "alias",
        "path": "json_lbm_02"
      },
      "core_lbm_01": {
        "type": "alias",
        "path": "tmp_lbm_01"
      },
      "core_lbm_02": {
        "type": "alias",
        "path": "tmp_lbm_02"
      }
    }
}

POST mytxindex-20230303/_search
{
  "query": {
    "match": {
      "lbm_01": "test01"
    }
  }
}

召回结果数据如下截图所示:

Elasticsearch 8.X 如何优雅的实现字段名称批量修改?

3.2 方案二,重新建模,然后 reindex 操作实现。

核心点介绍如下:

  1. 优先推荐使用模板 template,解决了字段名称相似的模板化匹配问题。 

  2. 预处理管道实现分两块:

  • 其一,script 实现了新旧字段的赋值;

  • 其二,remove 移除了不必要的老字段。 

优点:这种操作比较常见,中规中矩。

缺点:需要 reindex 迁移索引数据,且在迁移的时候做预处理操作。

具体实现如下:

#### step1:创建模板,有了模板,字段一键搞定
PUT _index_template/mytx_template_20230303
{
  "index_patterns": [
    "mytx_new_*"
  ],
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "dynamic_templates": [
        {
          "lbm_to_keyword": {
            "match_mapping_type": "string",
            "match": "lbm_*",
            "mapping": {
              "type": "keyword"
            }
          }
        },
        {
          "core_lbm_to_keyword": {
            "match_mapping_type": "string",
            "match": "core_lbm_*",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ]
    }
  }
}

#### step2:创建预处理管道
PUT _ingest/pipeline/mytx_pipeline_20230303
{
  "processors": [
    {
      "script": {
        "source": """
        ctx.lbm_01 = ctx.json_lbm_01;
        ctx.lbm_02 = ctx.json_lbm_02;
        ctx.core_lbm_01 = ctx.tmp_lbm_01;
        ctx.core_lbm_02 = ctx.tmp_lbm_02;
        """,
        "lang": "painless"
      }
    },
    {
      "remove": {
        "field": [
          "json_lbm_01",
          "json_lbm_02",
          "tmp_lbm_01",
          "tmp_lbm_02"
        ],
        "if": "ctx.json_lbm_01 != null && ctx.json_lbm_02 != null && ctx.tmp_lbm_01 != null && ctx.tmp_lbm_02 != null"
      }
    }
  ]
}

#### step3:数据迁移操作
POST _reindex
{
  "source": {
    "index": "mytxindex-20230303"
  },
  "dest": {
    "index": "mytx_new_001",
    "pipeline": "mytx_pipeline_20230303"
  }
}

#### step4:执行检索
POST mytx_new_001/_search

召回结果如下图所示:

Elasticsearch 8.X 如何优雅的实现字段名称批量修改?

3.3 方案三:解决遍历问题的终极方案

方案一、方案二都解决不了 N 个字段的问题。

假设有多个字段,不想一个字段一个字段的复制处理,也不想借助第三方脚本如shell 或者 python 处理。

那有没有更好的方案呢?方案三基于字段遍历实现,字段无非是 key:value 组合。

先通过:entry.getKey( )获取 key,然后基于 key 做逻辑判定,构造新的key,然后将旧value 复制给新 key。

最后,通过 putAll 更新。

PUT _ingest/pipeline/rename_fields_pipeline
{
  "processors": [
    {
      "script": {
        "source": """
          def new_fields = [:];
          for (entry in ctx.entrySet()) {
            String key = entry.getKey();
            if (key.startsWith('json_')) {
              key = key.replace('json_', '');
            } else if (key.startsWith('tmp_')) {
              key = 'core_' + key.replace('tmp_', '');
            }
            new_fields[key] = entry.getValue();
          }
          ctx.clear();
          ctx.putAll(new_fields);
        """
      }
    }
  ]
}


POST _reindex
{
  "source": {
    "index": "mytxindex-20230303"
  },
  "dest": {
    "index": "mytx_new_002",
    "pipeline": "rename_fields_pipeline"
  }
}

最终执行结果如下,和预期一致。

Elasticsearch 8.X 如何优雅的实现字段名称批量修改?

4、小结

类似问题即便给出了3种不同的实现方案,都能达到给定的业务需求。

但,仍然不建议业务中后期这么处理。更优的解决方案,推荐借助 Elasticsearch 建模阶段做好规划,避免中后期的类似上述问题的涉及大量数据迁移的大的改动。

更多实践想法,欢迎大家一起交流!!!

推荐阅读

  1. 全网首发!从 0 到 1 Elasticsearch 8.X 通关视频

  2. 重磅 | 死磕 Elasticsearch 8.X 方法论认知清单(2022年国庆更新版)

  3. 如何系统的学习 Elasticsearch ?

  4. 2023,做点事

更短时间更快习得更多干货!

和全球近 1900+ Elastic 爱好者一起精进!

Elasticsearch 8.X 如何优雅的实现字段名称批量修改?

比同事抢先一步学习进阶干货!文章来源地址https://www.toymoban.com/news/detail-406538.html

到了这里,关于Elasticsearch 8.X 如何优雅的实现字段名称批量修改?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • es head 新增字段、修改字段、批量修改字段、删除字段、删除数据、批量删除数据

    目录 一、新增字段 二、修改字段值 三、批量修改字段值 ​四、删除字段 五、删除数据/文档 六、批量删除数据/文档 put   http://{ip}:{port}/{index}/_mapping/{type}     其中,index是es索引、type是类型 数据: 例子: 注意:如果报错Types cannot be provided in put mapping requests, unless the in

    2024年02月04日
    浏览(57)
  • 使用Python批量修改文件名称

    下载了一些图片,想要更改其文件的名称。 试了许多方法,都不太理想。 于是想到了使用Python来实现。 需要用到的模块及函数: rename() 函数用于改变文件或文件夹的名称。它接受两个参数:原文件名和新文件名。 os.listdir(‘路径’)函数用于返回给定路径下的文件名称列表

    2024年02月15日
    浏览(47)
  • 批量修改文件名称不生效,命令不正确

    操作方法: 1.在需要修改文件名的文件夹中新建一个文本文档,然后在里面编辑如下内容(此处以修改 .jpg 图片为例): dir *.jpg /b rename.xls (上面这条命令是将该文件夹内所有后缀名为 .jpg 的文件名放入文件名为 rename.xls 的文件中,若后缀是docx,那就是dir *.docx /b rename.xls如

    2024年02月06日
    浏览(41)
  • SQ工具|2|ArcGIS数据结构(字段名称、字段长度、字段类型、允许为空)的修改

    方式一:借用ArcToolBox中的合并工具(方法来自于GIS思维) 数据管理工具常规合并 右侧四个按钮可实现添加字段、删除字段及调整字顺序的需求   右击目标字段,点击属性,即可实现更改字段名称、类型、长度及允许空值的功能。 点击确定后即可生成所需数据。 但! 我们使

    2024年02月13日
    浏览(94)
  • 文件夹路径保存不同,什么批量修改名称

    在日常工作中不知道大家有没有遇到过,需要批量修改文件夹名称,并且文件夹保存路径不同呢,像这种情况到底不能批量修改呢。我也问了很多身边的朋友,他们有的说,他一般都修改保存路径是同一个,还很少遇到像我这样情况,他们给的建议是,分次修改,一次修改同

    2024年02月05日
    浏览(54)
  • Python自动批量修改文件名称的方法大全

    本文介绍基于 Python 语言,按照一定命名规则 批量修改 多个文件的 文件名 的方法。已知现有一个文件夹,其中包括班级所有同学上交的作业文件,每人一份;所有作业文件命名格式统一,都是地信1701_姓名_学习心得格式。 现需要对每一位同学的作业文件加以改名,有很多种

    2024年02月02日
    浏览(71)
  • 如何使用ES做简单的时间条件过滤+模糊查询+精确匹配+关键字排除,查询 elasticsearch查询结果包含或排除某些字段、_source查询出需要的属性名称

    目录 一、时间条件过滤+模糊查询+精确匹配+排除 1. 查询出包含 log_geo 的数据 “wildcard”: { “message”: “log_geo” } 2. 查询某个时间段的数据 3. 条件查询与条件排除数据 4. from 表示起始的记录的ID 5. size 表示显示的记录数 6.sort排序 desc降序、asc升序  7.should查询在mysql中

    2024年01月18日
    浏览(70)
  • mybatis-plus 根据指定字段 批量 删除/修改

    mybatis-plus 提供了根据id批量更新和修改的方法,这个大家都不陌生 但是当表没有id的时候怎么办) 这个就不说了,就是因为不想手写SQL 所以才有这篇博客 mybatis plus 的 executeBatch 参考 mybatis plus 的updateBatchById 方法. 调用处: 接口 重写方法 实现 这种写法其实批量的效率还是比较慢的

    2024年02月13日
    浏览(41)
  • Elasticsearch 删字段及修改字段处理办法

    Elasticsearch是不能像mysql等关系型数据库直接删除字段的。 Elasticsearch删除字段大概分为以下几个步骤:(比如原索引名为index_name) 1、创建新索引(index_name1) 2、新索引创建新mapping(去掉要删除的字段) 3、原索引导出数据到新索引(index_name-index_name1) 4、删除原索引(也就

    2024年02月11日
    浏览(48)
  • ElasticSearch修改索引字段类型

    线上功能报错,一看日志是往es中添加数据报错,错误日志如下: 说是数据中有个字段类型转换错误,一查es脚本工具,果然生产es索引中categoryId这个字段是integer类型,而实际是long类型。 es不能直接修改索引字段类型,需要删除调新建,具体方法如下 我这次遇到问题的es索引

    2023年04月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包