默认情况下,如果将数据插入到不符合现有类型的字段,则抛出异常会引发异常。例如,如果已将字段创建为数字类型,则插入具有该字段的字符串值的文档会导致错误。
可以通过启用ignore_malformed
设置来更改此行为,这意味着会出于索引目的而忽略此类字段,但会保留在_source
文档中 - 这意味着无法搜索或汇总无效值,但仍包含在退回的文件中。
这是我们用例中的首选行为,但我们希望能够以某种方式找到这些文档,以便将来修复它们。
有没有办法以某种方式标记某些格式错误的字段被忽略的文档?我们完全控制文档插入过程,因此我们可以修改所有插入标记,或者进行试验插入或任何操作,以实现我们的目标。
答案 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查看如何分析文档并将其存储在反向索引中;如果是字符串字段,则可以看到“数组“存储为空字符串等。但是该字段将存在。
所以忘了倒排索引,让我们使用源代码!
滚动所有数据,直到找到异常,我使用一个小的python脚本进行搜索滚动,反序列化,并测试每个文档的字段类型(很长),但是我可以错误的文档ID列表。
使用脚本查询可能会很长,并且会使您的群集崩溃,请谨慎使用,也许作为post_filter
:
这里我要检索country_name
不是字符串的文档:
{
"_source": false,
"timeout" : "30s",
"query" : {
"query_string" : {
"query" : "locale:de_ch"
}
},
"post_filter": {
"script": {
"script": "!(_source.country_name instanceof String)"
}
}
}
您注意到,这是一项缺少的功能,我知道logstash会标记 文档失败,因此elasticsearch可以实现相同的功能。