Elasticsearch 8.x Java API中Update写入null值无效问题解决方法

Elasticsearch 8.x Java API中Update写入null值无效问题解决方法

Elasticsearch是一个广泛使用的开源分布式搜索和分析引擎,其强大的功能使得用户能够在大规模数据集上进行快速、准确的搜索、分析和可视化操作。ES适用于处理各种类型的数据,包括结构化、半结构化和非结构化数据,因此在大数据应用场景下得到了广泛的应用。

本文将详细介绍在Elasticsearch Java API中遇到的一个问题,即在进行Update操作时写入null值无效的情况,并提供了解决方案。同时,作者分享了在排查和解决问题过程中的一些经验和反思。

问题描述

在使用Elasticsearch 8.x的Java API时,根据需要可以使用以下方法来新增数据:

  • - Create:如果文档不存在,则创建新文档;如果文档已存在,则报错并发生异常,不会影响其他操作。

  • - Index:创建新文档或替换现有文档。

  • - Update:部分更新文档(设置upsert为true)。

然而,在大多数情况下,新增一条数据通常使用Update操作,因为我们不希望通过更新操作来覆盖整行数据。特别是在中间件同步过程中,往往需要处理多表汇聚的情况,这就需要依赖Update操作来仅更新某些字段,而不是替换整个文档。

然而,当作者使用BulkOperation构建多个Update操作时,发现将null值字段写入Elasticsearch的Index中时,该值无法正确写入。

问题排查

作者首先在Kibana控制台中进行实验,发现更新一条包含null值的文档是不可行的。这表明问题肯定存在于代码中。于是,作者将代码拆分出来进行测试。

首先,使用PUT命令将一条数据写入Elasticsearch:

PUT index_test/_doc/1
{
    "age": 12,
    "name": "John Doe"
}

然后,使用Java API对_id为1的数据进行修改:

RestClient restClient = RestClient.builder(new HttpHost("xxx", 9200)).build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient client8 = new ElasticsearchClient(transport);
String indexName = "index_test";
String esIdVal = "1";
Map<String, Object> doc = new HashMap<>();
doc.put("age", null);
doc.put("name", null);
BulkOperation op = new BulkOperation.Builder().update(i -> i.action(new UpdateAction.Builder<>()
                    .doc(doc)
                    .docAsUpsert(true)
                    .build()).id(esIdVal)).build();
List<BulkOperation> list = Collections.singletonList(op);
    
BulkResponse response = client8.bulk(builder -> builder.index(indexName).operations(list));
logger.info(response.toString());
client.shutdown();

运行结果为:

{
    ...
    "result":"noop"
    ...
}

返回结果中的result为noop,说明Elasticsearch实际上没有对文档进行更新操作。然而,请求的doc中携带了null值,这一现象令人困惑。作者甚至怀疑是Elasticsearch的Java API存在问题。

后来,在代码Review过程中,作者发现在初始化ElasticsearchTransport时,传入了new JacksonJsonpMapper()。通过查阅源码,作者发现JacksonJsonpMapper的默认初始化中配置了如下代码:

this(new ObjectMapper()
    .configure(SerializationFeature.INDENT_OUTPUT, false)
    .setSerializationInclusion(JsonInclude.Include.NON_NULL)
);

通过观察`setSerializationInclusion(JsonInclude.Include.NON_NULL)`这一行代码,作者恍然大悟。原来是序列化器的默认配置造成了问题。默认情况下,null值会被排除在序列化的过程之外,所以导致了null值无法正确写入Elasticsearch。

因此,作者决定自定义一个ObjectMapper,并将其传递给JacksonJsonpMapper来解决这个问题。

ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper(mapper));

在修改了代码后,null值成功地被写入到Elasticsearch中。

总结

本文详细介绍了在Elasticsearch 8.x Java API中遇到的Update写入null值无效的问题,并提供了解决方案。通过自定义ObjectMapper并将其传递给JacksonJsonpMapper,我们成功地实现了将null值写入Elasticsearch的目标。同时,在使用Elasticsearch Java API时需要注意序列化器的配置,以免出现类似的问题。

反思

在本文中,作者分享了在使用Elasticsearch 8.x Java API进行Update操作时遇到的一个问题,即写入null值无效。通过对代码的排查,作者发现问题源于序列化器的默认配置。解决方案是自定义ObjectMapper并将其传递给JacksonJsonpMapper。这个问题的出现让作者反思了在使用Elasticsearch时需要对其内部实现有足够的了解,并且需要更加谨慎地进行代码审核和测试,以及更加重视配置的影响。这些反思能够帮助我们更好地使用Elasticsearch,并避免一些潜在的问题。

关键词:Elasticsearch 8.x Java API, Update, null值, 排查, 解决文章来源地址https://www.toymoban.com/diary/java/616.html

到此这篇关于Elasticsearch 8.x Java API中Update写入null值无效问题解决方法的文章就介绍到这了,更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

原文地址:https://www.toymoban.com/diary/java/616.html

如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用
Http状态码解析大全_记录HTTP 状态值的含义
上一篇 2023年12月25日 14:28
下一篇 2023年12月25日 14:43

相关文章

  • Elasticsearch Java API 的使用-更新索引(update & upset)与 Bulk的批量更新

    Java更新索引(update upset) update 更新使用UpdateRequest(update类型更新,只能更新) upset 要用IndexRequest设定添加文档,UpdateRequest设定更新文档,设定upset执行有则修改无则更新(upset类型更新,文档不存在时创建) 基于Bulk的批量更新(update upset) 动态的更新一个 documents 中的任

    2024年02月11日
    浏览(23)
  • Elasticsearch Document Update API详解、原理与示例

    private int retryOnConflict = 0:更新冲突时重试次数。 private RefreshPolicy refreshPolicy = RefreshPolicy.NONE:刷新策略。NONE:代表不重试; private ActiveShardCount waitForActiveShards = ActiveShardCount.DEFAULT:执行操作之前需要等待激活的副本数,已在《Elasticsearch Document Get API详解、原理与示例》中详

    2024年04月22日
    浏览(9)
  • Windows 10 执行wsl命令报错: --list -o命令行选项无效 --update命令行选项无效等解决办法

    问题说明 在使用wsl命令的时候, wsl --update , wsl --list -o 等关键的命令都显示命令行选项无效 但是wsl这个命令却又是一个有效的命令 解决办法 1.卸载旧版本的WSL 没有子系统可以跳过这个步骤 打开命令提示符或PowerShell窗口(以管理员身份运行),然后运行以下命令以卸载W

    2024年02月12日
    浏览(22)
  • springboot项目出现”java: 错误: 无效的源发行版:17“问题解决方案

    在我个人遇到此问题的情况下,出现此错误的原因是springboot的版本与java版本不一致 在spring3更新后,idea在创建springboot项目时会默认选择spring3,哪怕你选择的是 java8 的版本 idea默认选择spring3 在你以java8创建spring3的项目后,就一定会出现”java: 错误: 无效的源发行版:17“,如

    2024年02月01日
    浏览(31)
  • Java 数据库改了一个字段, 前端传值后端接收为null问题解决

    前端传值后端为null的原因可能有很多种,我遇到一个问题是,数据库修改了一个字段,前端传值了,但是后台一直接收为null值, 原因排查: 1、字段没有匹配上,数据库字段和前端字段传值不一致 2、大小写一定要注意 这个疏忽大意了 以上都改了还是null ~~~~! 3、get set方法

    2024年02月10日
    浏览(29)
  • Elasticsearch写入数据之elasticsearch-java

    在《Elasticsearch8.4.2在windows系统下的安装介绍》中介绍了如何安装ES,那么安装成功后改如何将数据写入到ES呢?写入ES数据的方式有很多,本次将介绍一种写入方式elasticsearch-java来写入数据到ES,elasticsearch-java是官方提供的java sdk写入方式,用户只需要配置相关参数就可以方便

    2024年02月11日
    浏览(20)
  • Elasticsearch集群索引写入失败[FORBIDDEN/12/index read-only / allow delete (api)]处理流程

    操作系统:CentOS 7.3 软件版本:elasticsearch-6.7.2 正常将数据写入到Elasticsearch时,发现写入失败,出现如下报错 检查Elasticsearch集群的active master节点的日志,并没有发现error,但有WARN告警,显示与 flood stage disk watermark [90%] 有关。 上下文有 low disk watermark [80%] 的INFO日志信息,再次

    2024年02月10日
    浏览(28)
  • Android 11/12 app-lint 系统Update-API时Lint检查问题

    这种方式你可以其他博客也有 但是要每个类和方法都加上 @SuppressLint 太麻烦了 我才不要这样呢 1. 打开 frameworks/base/Android.bp 文件 2. 搜索找到这个字段 metalava_framework_docs_args 3. 然后在最后面添加   --api-lint-ignore-prefix xxxx 芜湖 成功啦

    2024年02月11日
    浏览(25)
  • Elasticsearch并发写入版本冲突解决方案

    搜索公众号, AmCoder 干货及时送达👇  众所周知,es经常被用于存储日志数据,其中在某些场景下,日志产生的时机不同,并且需要将多类具备关联关系的日志写入同一个document,就会带来同一个文档可能会被其它文档覆盖,或者missing等问题。 大家都知道es是不支持事务的,

    2023年04月19日
    浏览(21)
  • Mybatis使用update更新值为null时不生效

    该文章纯属记录使用过程中遇到的问题更新null值没有生效的问题解决办法,内容较为简单。 1.出现的问题 前端修改数据时把属性内容删除然后进行保存,默认传的null,后端更新时属性值为null,然后调用updateById进行更新时发现该属性还是原来的值: 后面百度发现该update方法

    2024年02月04日
    浏览(19)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包