Elasticsearch:ignore_malformed,映射异常的解药

这篇具有很好参考价值的文章主要介绍了Elasticsearch:ignore_malformed,映射异常的解药。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ignore_malformed,Elasticsearch,Elastic,elasticsearch,大数据,搜索引擎,全文检索,运维

我们知道在文档摄入到 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 的默认设置。文章来源地址https://www.toymoban.com/news/detail-735429.html

到了这里,关于Elasticsearch:ignore_malformed,映射异常的解药的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Elasticsearch的索引和映射:动态映射

    Elasticsearch是一个基于分布式搜索和分析引擎,可以提供实时的、可扩展的、高性能的搜索功能。它是一个基于Lucene的搜索引擎,具有高度可扩展性和高性能。Elasticsearch支持多种数据类型,如文本、数字、日期等,并提供了丰富的查询功能。 在Elasticsearch中,数据是通过索引和

    2024年02月20日
    浏览(47)
  • OOD 使用基于提示的特征映射生成用于视频异常检测

    paper link 本文提出了使用 提示引导特征映射 的生成式视频异常检测框架,作者来自中山大学,文章发表在cvpr2023 作者首先分析了现有方法并指出当前面临的两个问题 大多数视频异常检测方法通过在训练阶段学习正常事件的分布,并在测试阶段检测分布外样本来决问题。显著的

    2024年02月09日
    浏览(51)
  • ElasticSearch 基础(五)之 映射

    本文主要内容转载于:ES Doc - mapping。 映射(Mapping) 是定义文档及其包含的字段如何存储和索引的过程。 每个文档都是字段的集合,每个字段都有自己的数据类型。映射数据时,创建映射定义,其中包含与文档相关的字段列表,决定字段使用什么分词器解析,是否有子字段

    2024年02月01日
    浏览(36)
  • Elasticsearch(2)——映射关系

    1 什么是映射 映射(mapping)就像数据库中的 Schema ,描述了文档可能具有的字段或属性、每个字段的 数据类型,比如 Text,Keyword,Integer 或 Date ,以及 Lucene 是如何索引和存储这些字 段的。 Elasticsearch 支持如下简单字段类型: (1) 字符串: text,keyword (2)整数:byte,sho

    2024年02月12日
    浏览(35)
  • Elasticsearch映射操作(八)

            在使用数据之前,需要构建数据的组织结构。这种组织结构在关系型数据库中叫作表结构,在ES中叫作映射。         作为无模式搜索引擎,ES可以在数据写入时猜测数据类型,从而自动创建映射。但有时ES创建的映射中的数据类型和目标类型可能不一致。当需

    2023年04月09日
    浏览(30)
  • Elasticsearch的映射操作

    本文来记录下Elasticsearch的映射操作 Elasticsearch与mysql数据库对比 映射的概述 有了索引库,等于有了数据库中的 database。 索引库(index)中的映射,类似于数据库(database)中的表结构(table)。 创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型

    2024年01月21日
    浏览(28)
  • Elasticsearch删除映射类型

    官方解释:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html 在elasticsearch6.0.0或更高的版本中创建索引仅能包含单个映射类型。在具有多种映射类型的5.x版本中创建的索引将继续像以前一样在elasticsearch6.x中运行。类型将在elasticsearch7.0.0中的API中弃用,并在8.0.0中完

    2024年02月06日
    浏览(36)
  • 14. Elasticsearch动态映射-1

    14.1 映射 类型和字段的信息存储(包含)在映射(mapping)中 Elasticsearch支持以下简单字段类型: 14.2 映射规则 Elasticsearch将使用动态映射猜测字段类型,这类型来自于JSON的基本数据类型,使用以下规则: 查看映射 14.3 动态映射 Elasticsearch最重要的功能之一是不必首先创建ind

    2023年04月08日
    浏览(26)
  • Elasticsearch 映射Mappings (三)

    本文主要记录映射Mappings的作用、类型、ES常用数据类型、常见参数、重要的数据类型、映射配置、映射模板。 静态参数使不可修改的,所以mappings里的配置需要谨慎行事 mapping类似Mysql中的表结构,在Maping里包含了一些属性,比如字段名称、类型、字段使用的分词器、是否评

    2024年02月16日
    浏览(42)
  • Elasticsearch映射与字段类型

    Elasticsearch映射与字段类型 Elasticsearch是一个分布式、实时的搜索和分析引擎,基于Lucene库构建。它可以快速、高效地索引、搜索和分析大量数据。在Elasticsearch中,数据以文档的形式存储,每个文档都有一个唯一的ID。文档可以存储在一个索引中,索引可以存储在一个集群中。

    2024年02月22日
    浏览(61)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包