在Elasticsearch中更新文档未将自定义分析器应用于字段数据

问题描述

我有一个字段,上面有一个自定义分析器,用于将数据转换为小写。

分析仪定义为:

"analysis" : {
      "analyzer" : {
        "custom_keyword_analyzer" : {
          "filter" : [
            "lowercase"
          ],"type" : "custom","tokenizer" : "keyword"
        }
      }
    }

在字段上的映射如下:

"Field" : {
        "type" : "text","fields" : {
          "raw" : {
            "type" : "keyword"
          }
        },"copy_to" : [
          "all_field"
        ],"analyzer" : "custom_keyword_analyzer","fielddata" : true
      }

当使用Field中的数据正常创建文档时,分析仪工作正常。字段包含小写的数据,字段.raw具有原始的未分析数据。

但是,如果在Field中创建的文档中没有任何内容,但后来又进行了更新,则不使用分析器,Field中包含未分析的数据,而Field.raw为空。

我尝试用python手动编写批量更新脚本,还尝试使用_update_by_query执行更新。在任何情况下,我都无法让分析仪处理更新的数据。

解决方法

我不知道您如何验证更新的文档对分析仪没有影响,下面是一个完整的示例,向您展示它的工作原理以及如何检查它。

根据您的定义进行索引映射

{
    "settings": {
        "analysis": {
            "analyzer": {
                "custom_keyword_analyzer": {
                    "filter": [
                        "lowercase"
                    ],"type": "custom","tokenizer": "keyword"
                }
            }
        }
    },"mappings": {
        "properties": {
            "title": {
                "type": "text","fields": {
                    "raw": {
                        "type": "keyword"
                    }
                },"copy_to": [
                    "all_field"
                ],"analyzer": "custom_keyword_analyzer","fielddata": true
            }
        }
    }
}

索引样本文档

{
   "title" : "Hello world"
}

检查倒排索引中的分析值

在下面的查询中使用_search端点

{
  "docvalue_fields": [
    "title","title.raw"
  ],"query": {
        "term": {
            "_id": 1
        }
    }
}

上述查询结果

  "_source": {
                    "title": "Hello world" // actual indexed content 
                },"fields": {
                    "title.raw": [
                        "Hello world" // same as keyword analyzer
                    ],"title": [
                        "hello world" // notice lowercased `h`.
                    ]
                }
            }

现在使用PUT API更新文档

{
   "title" : "Hello world Updated" // note `U` in `Updated`
}

然后再次使用相同的_search查询

"_source": {
                    "title": "Hello world Updated"
                },"fields": {
                    "title.raw": [
                        "Hello world Updated"
                    ],"title": [
                        "hello world updated" // note lowercase
                    ]
                }

如您所见,即使在更新文档分析器之后,它仍然具有影响力以及它如何工作并可以被验证,这是非常核心的功能,不能被破坏,并且可能在验证及以上时缺少某些内容方法应该给您一些识别错误的方法