当前位置:   article > 正文

ES模糊查询不区分大写_es keyword 不区分大小写查询

es keyword 不区分大小写查询

一、 概述

最近接到新任务,产品说名称能支持模糊搜索,且不区分大小写。
以为是数据库操作,那岂不是easy,分分钟的事情,往往事情觉得简单的时候就不简单了,脑子忽然闪现想起该模块数据是放在ES里的,ES模糊查询不分大小写???ES新手小白两眼抹黑,待我调研调研>>>>>

一顿操作ES海洋里遨游一圈~~~终于找到了,首先了解到
ES5.x以上版本使用text和keyword作为字符串类型取代之前版本的string类型。

  • 字符串 - text:用于全文索引,该类型的字段将通过分词器进行分词,最终用于构建索引
  • 字符串 - keyword:不分词,只能搜索该字段的完整的值,只用于 filtering

两者实现方式略微不同,实质本质一样都是使用分析器。注意ES中的字段是什么类型的。

ES里提供了很多分析器,可以上官网看看,这样就会明白为什么这么做了,这里不多解释,ES的text analyer

二、 keyword类型模糊查询不区分大小写

官方给出了一个解决方案,使用normalizer来解决,normalizer是keyword的一个属性,可以对keyword生成的单一term,query_string做进一步的处理。修改setting,需要先关闭索引,修改后再打开索引,防止数据丢失.

  1. settings添加分析器
# 关闭索引
​POST test_index/_close
  
PUT test_index/_settings
{
    "analysis": {
      "normalizer": {
        "lowercase_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": [
            "lowercase"
          ]
        }
      }
    }
}

#打开索引 
POST test_index/_open

# 查看settings看是否加上 lowercase_normalizer
GET test_index/_settings 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  1. 添加新字段且设置分析器
    这里选择的是新的字段
​PUT test_index/station/_mapping
{
  "properties": {
    "querName": {
      "type": "keyword",
      "normalizer": "lowercase_normalizer"
    }
  }
}

# 查看新的mapping
GET test_index/_mapping 

# 同步数据: 把原来的字段值同步到新字段
POST test_index/_update_by_query
{
  "script": {
    "lang": "painless",
    "source": "if (ctx._source.queryName== null) {ctx._source.queryName= ctx._source.name.toLowerCase()}"
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

三、text类型模糊查询不区分大小写

text类型的需要写一个分析器,然后添加到text类型字段上

--- 关闭索引
POST test_index/_close

--- 新增按小写查询分析器
PUT test_index/_settings
{  "analysis" : {
          "analyzer" : {
            "ngram-analyzer" : {
              "type" : "custom",
              "tokenizer" : "ngram_tokenizer"
            },
            "ngram-lowercase" : {
              "type" : "custom",
              "tokenizer" : "ngram_tokenizer",
              "filter":"lowercase"
            }
          }
        }
}

 
--- 打开索引
POST test_index/_open

--- 新增queryName字段,支持不区分大小写查询,且设置查询分析器
PUT  test_index/_mapping
{
  "properties": {
    "queryName": {
      "type": "text",
      "analyzer" : "ngram-analyzer",
      "search_analyzer":"ngram-lowercase"
    }
  }
}

--- 处理历史数据queryName值为name的值
POST test_index/_update_by_query
{
  "script": {
    "lang": "painless",
    "source": "if (ctx._source.queryName== null) {ctx._source.queryName= ctx._source.name.toLowerCase()}"
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

你以为到这里就成功了????我也这么以为,但是高兴太早了,因为我发现ES的数据里有大写字母时,忽略大小写功能不全好使,百思不得其解,why???。

例如:ES的 [{"queryName":"TEst1"},{"queryName":"TEST2"},{"queryName":"tesst3"}]

查询条件为"TEST"或"test"或"Test" 期望是查询出来三条,但是大写的查询不出来;
  • 1
  • 2
  • 3

但是我把ES的queryName都转化为小写的,嘿嘿嘿~~~~,模糊查询忽略大小写好使了,这里我也不是很清楚,待调研ing ,若是有知道的可以交流交流。
queryName.toLowerCase();

例如:ES的 [{"queryName":"test1"},{"queryName":"test2"},{"queryName":"test3"}]

查询条件为"TEST"或"test"或"Test" 期望是查询出来三条, 实际查询也是三条;
GET test_index/_search
{"query": {
  "bool": {
    "must": [
         {
        "match_phrase" : {
          "queryName" : {
            "query" : "Test"
          }
        }
      }
    ]
  }
}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/800800
推荐阅读
相关标签
  

闽ICP备14008679号