Elasticsearch:ignore_malformed,映射异常的解药

news2024/11/17 13:31:39

我们知道在文档摄入到 Elasticsearch 时,如果文档的字段在 mapping 中已经有定义,而当前的文档的字段的类型和之前的类型是不一样的情况下,那么我们该如何处理呢?通常由如下的几种方法:

  • 使用 coerce 属性。在这种情况下,即便不同类型的数据被写入到相应的字段,在能够相互转换的情况下,它的写入也可以是成功的。请详细阅读文章 “Elasticsearch:Elasticsearch 中的数据强制匹配” 及 “Elasticsearch:如何将浮点值存储到整型字段中”。
  • 通过 ingest pipeline 或者 Logstash 进行数据转换再写入到 Elasticsearch。

上面的方法只适用于在能够转换的条件下才可以实现,比如 “1” => 1 的转换。但是,在有些情况下,我们的这种转换是根本不可行的,比如 "one" => 1。首先这种数据的类型是根本不一样,而且即便强制转换,也会失败。

那么出现这种情况,一种是直接丢弃该文档,这会造成文档的丢失,即使是一个字段的类型不匹配。那么我们是否有其它的方式呢来处理这个文档呢?比如丢失这个不符合的字段,而摄入其它的字段。

忽略不符合索引映射的字段,并避免在使用 Elasticsearch 摄取期间丢弃文档。一个几乎不为人知的名为 ignore_malformed 的设置如何在因为单个字段格式错误而完全删除文档或忽略该字段并无论如何摄取文档之间产生差异。

ignore_malformed

有时你对收到的数据没有太多控制权。 一个用户可以发送一个 login 字段,它是一个 date,另一个用户可以发送一个 login 字段,它是一个电子邮件地址。

尝试将错误的数据类型索引到字段中会默认引发异常,并拒绝整个文档。 ignore_malformed 参数,如果设置为 true,则允许忽略异常。 格式错误的字段没有被索引,但文档中的其他字段被正常处理。

在本文中,我将解释设置 ignore_malformed 如何影响 100% 的丢弃率和 100% 的成功率(即使只是忽略一些格式错误的字段)。

映射是如何工作的

我喜欢将 Elasticsearch 视为一个基于文档的 NoSQL 数据库,其中不需要预先定义索引的模式。 Elasticsearch 将从第一个文档或包含新字段的任何后续文档推断 schema。

或者,你可以预先提供一个 schema(在 Elasticsearch 术语中称为映射 mapping),并且你的所有文档都需要遵循该 schema。

实际上,情况并非非黑即白。 你还可以为每个文档提供仅涵盖部分字段(可能是最常见的)的部分模式,并让 Elasticsearch 找出更多动态字段的 schema。

当数据格式错误时会发生什么?

无论你是预先指定映射还是 Elasticsearch 自动推断映射。 如果文档只显示一个与索引映射不匹配的字段,Elasticsearch 将删除整个文档并在客户端日志中返回警告。

如果客户不查看这些日志而错过了警告,就会出现大问题。 他们可能永远不会发现哪里出了问题,或者更糟的是,如果所有后续文档的格式都错误,Elasticsearch 甚至可能会完全停止摄取数据。

上述情况听起来非常灾难性,但完全有可能发生,尤其是在你无法完全控制数据质量的情况下。 想想用户生成的文档。

Elasticsearch 中可能有一个非常未知的设置可以准确解决上述问题。 这个字段从 Elasticsearch 2.0 开始就有了。 我们在这里谈论古老的历史,因为在撰写本文时最新版本是 8.8。

示例用例

为了更方便地与 Elasticsearch 交互,我将在这里使用 Kibana(Elasticsearch 的前端工具)和 Dev Tools 控制台。

以下示例摘自 Elasticsearch 官方文档。

我在这里通过提供一些关于幕后发生的事情的更多细节来扩展这个例子。

首先,我们要定义 2 个字段,它们都是整数类型,但只有一个字段定义了 ignore_malformed 。

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "number_one": {
        "type": "integer",
        "ignore_malformed": true
      },
      "number_two": {
        "type": "integer"
      }
    }
  }
}

如果你尝试使用以下命令获取生成的映射:

GET my-index-000001/_mapping

你讲得到如下的结果:

{
  "my-index-000001": {
    "mappings": {
      "properties": {
        "number_one": {
          "type": "integer",
          "ignore_malformed": true
        },
        "number_two": {
          "type": "integer"
        }
      }
    }
  }
}

然后我们提取两个示例文档:

PUT my-index-000001/_doc/1
{
  "text":       "Some text value",
  "number_one": "foo" 
}

PUT my-index-000001/_doc/2
{
  "text":       "Some text value",
  "number_two": "foo" 
}

文档 1 被正确摄取,而文档 2 反而返回以下错误消息。

{
  "error": {
    "root_cause": [
      {
        "type": "document_parsing_exception",
        "reason": "[3:17] failed to parse field [number_two] of type [integer] in document with id '2'. Preview of field's value: 'foo'"
      }
    ],
    "type": "document_parsing_exception",
    "reason": "[3:17] failed to parse field [number_two] of type [integer] in document with id '2'. Preview of field's value: 'foo'",
    "caused_by": {
      "type": "number_format_exception",
      "reason": "For input string: \"foo\""
    }
  },
  "status": 400
}

如果你随后使用以下查询搜索相同的索引:

GET my-index-000001/_search
{
  "fields": [
    "*"
  ],
  "_source": true
}

你会看到只有第一个文档(id=1)被正确摄取。

{
  "took": 659,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "my-index-000001",
        "_id": "1",
        "_score": 1,
        "_ignored": [
          "number_one"
        ],
        "_source": {
          "text": "Some text value",
          "number_one": "foo"
        },
        "fields": {
          "text.keyword": [
            "Some text value"
          ],
          "text": [
            "Some text value"
          ]
        },
        "ignored_field_values": {
          "number_one": [
            "foo"
          ]
        }
      }
    ]
  }
}

从上面的 JSON 响应中,你可以注意到几件事:

  • 现在有一个 _ignored 类型的字段,其中包含在摄取此文档时被忽略的所有字段的列表。
  • 有一个字段 ignored_field_values 带有忽略字段及其值的字典。
  • 字段 source 包含未修改的原始文档。 如果你想稍后修复映射问题,这将特别有用。

结论

你可以从今天开始在你的索引上使用 ignore_malformed ,只需添加到你的索引设置,创建映射时添加到单个字段,或者添加到索引模板以使具有特定索引模式的所有索引成为默认选项。 为了简洁起见,我不会在这里展示如何将此设置用于索引、索引模板或组件模板。 请参阅官方文档或继续关注有关该主题的更多文章。

Elastic 目前正在努力使此设置成为 Elasticsearch 8.9 的默认设置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/670682.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python微信公众号推送消息

目录 准备数据 接口 代码 微信公众号开发文档:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html 准备数据 1、微信公众号注册:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?tsandbox/login 2、注册成功后可生…

基于TCP/UDP的Socket编程

---- socket概述: socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。 socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写…

springboot启动流程 (3) 自动装配

在SpringBoot中,EnableAutoConfiguration注解用于开启自动装配功能。 本文将详细分析该注解的工作流程。 EnableAutoConfiguration注解 启用SpringBoot自动装配功能,尝试猜测和配置可能需要的组件Bean。 自动装配类通常是根据类路径和定义的Bean来应…

005 Settings可以直接通过AndroidStudio安装并调试(二)——Settings 打release包遇到的问题

一.背景 Settings迁移到AndroidStudio中直接打release包是有各种问题的,打不出来包,这里我们详细来描述下Settings打包出现的问题及解决方案。 二.Type com.android.settingslib.widget.BuildConfig is defined multiple times 首先遇到的拦路虎,也是最繁琐的包名冲突,之…

为什么配电室总出故障?这一点你做对了吗

配电室是供电系统中非常关键的组成部分,负责对电能进行分配和控制。然而,传统的配电室监控方式存在一些局限性,如人工巡检的局限性、监测数据获取困难、安全隐患无法及时发现等。 因此,为了提高配电室的管理水平、确保供电系统的安…

剑指offer03.数组中重复的数字

看到这道题的第一眼想到的是先给它排序,然后双指针从左往右遍历,写了一个冒泡排序,但是我想到了应该会超时,因为冒泡时间复杂度是n的平方,输入大小时10000,肯定会超时,然后右又看了一下题目看到…

SpringCloud Alibaba入门之用户子模块开发

在上一章的基础上进行子模块的开发SpringCloud Alibaba入门之创建多模块工程_qinxun2008081的博客-CSDN博客 一、引入SpringBoot 我们在父项目统一管理引入的jar包的版本。我们采用父项目中以depencyMangement方式引入spring-boot,子项目依赖parent父配置即可。 &…

YGG 公会发展计划(GAP)第三季总结

2023年5月6日,Yield Guild Games(YGG)结束了其代币分配系统——公会发展计划(GAP)的第三季,向社区成员提供了更多奖励,以表彰他们对公会和参与游戏的宝贵贡献。 第三季对 GAP 进行了一些升级&am…

uniapp和springboot微信小程序开发实战:前端架构之微信小程序开发表单提交功能

文章目录 前言前端代码后端代码controller层service层总结前言 基本上很多项目都有类似于意见反馈、留言等形式的表单提交功能,今天给大家介绍的是使用uniapp和vue组件实现的表单提交功能。其效果如下: 前端代码 <template><view class="body"><…

Jmeter接口测试-MD5加密-请求验签

目录 前言&#xff1a; 第一部分&#xff1a;先准备好Jmeter 第二部分&#xff1a;编写MD5加密-请求验签的脚本 第三部分&#xff1a;执行脚本 前言&#xff1a; JMeter是一款常用的接口测试工具&#xff0c;对于需要进行加密验证的接口&#xff0c;我们可以使用MD5加密算…

HOOPS Exchange SDK 2023 Crack

领先的 CAD 导入和导出库 使用 HOOPS Exchange SDK 将 30 多种 CAD 文件格式导入您的应用程序以进行 CAD 数据转换&#xff0c;通过单个 API 对 2D 和 3D CAD 文件格式&#xff08;包括 CATIA、SOLIDWORKS、 Inventor、Revit™™、Creo、NX™、Solid Edge 等&#xff09;提供快…

Nvidia官方解码性能

NVIDIA VIDEO CODEC SDK | NVIDIA Developer 1080P解码性能&#xff1a; 720P解码性能&#xff1a; 详细的参见官方的链接地址&#xff0c;对于GPU的解码fps能力&#xff0c;可以作为评估参照&#xff01;

【服务器远程工具】一款好用的xshell

这里写目录标题 背景Tabby简介安装使用SSHSFTPPowerShellGit 设置外观颜色快捷键窗口 插件支持总结 背景 作为一名后端开发&#xff0c;我们经常需要和Linux系统打交道&#xff0c;免不了要使用Xshell这类终端工具来进行远程管理。今天给大家推荐一款更炫酷的终端工具Tabby&…

C++核心编程——详解函数模板

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.模板的基础知识①为什么有模板&#xff1f;②初识模板 二.函数模板①函数模板的定义②函数模板的使用③函数模板实例化1️⃣隐式实例化2️⃣显…

QAC用户使用手册

文章目录 1 QAC介绍1.1 QAC简介1.2 QAC dashboard简介 2 QAC使用&#xff08;基本操作&#xff09;2.1 创建QAC工程2.2 创建QAC工程2.3 添加代码到QAC工程2.4 添加代码到QAC工程2.5 上传分析报告及结果 1 QAC介绍 1.1 QAC简介 Helix QAC是Perforce公司(原PRQA公司)产品,主要用…

「Java核心技术大会 2023」——小解送书第三期

目录 共同深入探讨 Java 生态&#xff01;直播预约&#xff1a;视频号“IT阅读排行榜” 抽奖 大会简介 人工智能在22年、23年的再次爆发让Python成为编程语言里最大的赢家&#xff1b;云原生的持续普及令Go、Rust等新生的语言有了进一步叫板传统技术体系的资本与底气。我们必…

Android studio项目编译进安卓源码中

最近要做一个Android 8.1 的launcher &#xff0c;在Androidstudio上开发好基本功能后&#xff0c;移到Android源码中编译 1.在源码中创建代码目录 我开发基于展讯9820e平台&#xff0c;在如下目录创建好对应名字的文件夹 \vendor\sprd\platform\packages\apps\xxxLauncher创…

回收站清空了怎么恢复?3个妙招恢复数据

回收站被人为清空&#xff0c;被放入回收站的文件因时间过久而被电脑自动删除时&#xff0c;回收站里的数据清空了还能找到吗&#xff1f;是可以的这3个小妙招可以帮你还原回收站的数据&#xff01; 妙招一&#xff1a;借助注册表还原回收站清空的数据 可以尝试借助注册表还原…

Bootstrap 环境安装

文章目录 Bootstrap 环境安装下载 Bootstrap 文件结构预编译的 BootstrapBootstrap 源代码 HTML 模板实例Bootstrap CDN 推荐 Bootstrap 环境安装 Bootstrap 安装是非常容易的。本章将讲解如何下载并安装 Bootstrap&#xff0c;讨论 Bootstrap 文件结构&#xff0c;并通过一个实…

常见的Jmeter参数化方式总结

目录 前言&#xff1a; 参数化概念 参数化方式 二、用户变量 三、CSV数据文件 四、函数助手 前言&#xff1a; 在进行接口性能测试时&#xff0c;我们通常需要针对不同的场景进行参数化操作。JMeter是一款强大的性能测试工具&#xff0c;它提供了多种参数化方式&#xff0c;方便…