在不使用映射的情况下对数字字段进行Elasticsearch通配符查询

问题描述

我正在寻找一个有创意的解决方案,因为我不能使用映射,因为解决方案已经在生产中。 我有这个查询

            {
              "size": 4,"query": {
                "bool": {
                  "filter": [
                    {
                      "range": {
                        "time": {
                          "from": 1597249812405,"to": null,}
                      }
                    },{
                      "query_string": {
                        "query": "*181*","fields": [
                          "deId^1.0","deTag^1.0",],"type": "best_fields","default_operator": "or","max_determinized_states": 10000,"enable_position_increments": true,"fuzziness": "AUTO","fuzzy_prefix_length": 0,"fuzzy_max_expansions": 50,"phrase_slop": 0,"escape": false,"auto_generate_synonyms_phrase_query": true,"fuzzy_transpositions": true,"boost": 1
                      }
                    }
                  ],"adjust_pure_negative": true,"boost": 1
                }
              },"sort": [
                {
                  "time": {
                    "order": "asc"
                  }
                }
              ]
            }

“ deId”字段是elasticsearch中的整数,并且查询不返回任何内容(尽管应该), 是否有解决方案,可以在不使用需要映射的多字段选项的情况下在数字字段中搜索通配符?

解决方法

索引整数后,ES不会将单个数字视为位置敏感的标记。换句话说,不可能直接对数字数据类型执行通配符。

有一些次优的解决方法(请考虑脚本和String.substring),但最简单的方法是将这些整数转换为字符串。

让我们看一个示例deId的123 181 994:

POST prod/_doc
{
  "deId_str": "123181994"
}

然后

GET prod/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "query_string": {
            "query": "*181*","fields": [
              "deId_str"
            ]
          }
        }
      ]
    }
  }
}

像魅力一样工作。

由于索引/映射已经在生产中,因此请查看_update_by_query并在一次调用中将所有必要的数字字符串化。之后,如果您不想(和/或无法)在索引时传递字符串,请使用ingest pipelines为您进行转换。