在Elasticsearch中查找触发`ignore_malformed`的文档

时间:2017-08-28 14:00:41

标签: elasticsearch malformed

默认情况下,如果将数据插入到不符合现有类型的字段,则抛出异常会引发异常。例如,如果已将字段创建为数字类型,则插入具有该字段的字符串值的文档会导致错误。

可以通过启用ignore_malformed设置来更改此行为,这意味着会出于索引目的而忽略此类字段,但会保留在_source文档中 - 这意味着无法搜索或汇总无效值,但仍包含在退回的文件中。

这是我们用例中的首选行为,但我们希望能够以某种方式找到这些文档,以便将来修复它们。

有没有办法以某种方式标记某些格式错误的字段被忽略的文档?我们完全控制文档插入过程,因此我们可以修改所有插入标记,或者进行试验插入或任何操作,以实现我们的目标。

2 个答案:

答案 0 :(得分:1)

您可以使用exists查询查找此字段不存在的文档,请参阅此示例

PUT foo
{
  "mappings": {
    "bar": {
      "properties": {
        "baz": {
          "type": "integer",
          "ignore_malformed": true
        }
      }
    }
  }
}

PUT foo/bar/1
{
  "baz": "field"
}

GET foo/bar/_search
{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must_not": [
            {
              "exists": {
                "field": "baz"
              }
            }
          ]
        }
      }
    }
  }
}

虽然没有专门的机制,但是此搜索还会找到未故意设置字段的文档

答案 1 :(得分:0)

当您在elasticsearch上进行搜索时,您不能在文档源上而是在包含已分析数据的倒排索引上进行搜索。

ignore_malformed标志表示“始终存储文档,如果可能,进行分析”。

您可以尝试创建格式错误的文档,并使用_termvectors API查看如何分析文档并将其存储在反向索引中;如果是字符串字段,则可以看到“数组“存储为空字符串等。但是该字段将存在。

所以忘了倒排索引,让我们使用源代码!

  1. 滚动所有数据,直到找到异常,我使用一个小的python脚本进行搜索滚动,反序列化,并测试每个文档的字段类型(很长),但是我可以错误的文档ID列表。

  2. 使用脚本查询可能会很长,并且会使您的群集崩溃,请谨慎使用,也许作为post_filter

这里我要检索country_name不是字符串的文档:

{
   "_source": false,
   "timeout" : "30s",
    "query" : {
        "query_string" : {
            "query" : "locale:de_ch"
        }
    },
    "post_filter": {
        "script": {
            "script": "!(_source.country_name instanceof String)"
        }
    }
}
  • “ _ source:false” =>我只需要文档ID
  • “超时” =>防止崩溃
  

您注意到,这是一项缺少的功能,我知道logstash会标记   文档失败,因此elasticsearch可以实现相同的功能。