聽說你還沒掌握 ElasticSearch Normalizer 的使用方法?

在 Elasticsearch 中處理字符串類型的數據時,如果我們想把整個字符串作為一個完整的 term 存儲,我們通常會將其類型 type 設定為 keyword。但有時這種設定又會給我們帶來麻煩,比如同一個數據再寫入時由於沒有做好清洗,導致大小寫不一致,比如 apple、Apple兩個實際都是 apple,但當我們去搜索 apple時卻無法返回 Apple的文檔。要解決這個問題,就需要 Normalizer出場了。廢話不多說,直接上手看!

1. 上手

我們先來重現一下開篇的問題

PUT test_normalizer

{

"mappings": {

"doc":{

"properties": {

"type":{

"type":"keyword"

}

}

}

}

}

PUT test_normalizer/doc/1

{

"type":"apple"

}

PUT test_normalizer/doc/2

{

"type":"Apple"

}

# 查詢一

GET test_normalizer/_search

{

"query": {

"match":{

"type":"apple"

}

}

}

# 查詢二

GET test_normalizer/_search

{

"query": {

"match":{

"type":"aPple"

}

}

}

大家執行後會發現 查詢一返回了文檔1,而 查詢二沒有文檔返回,原因如下圖所示:

聽說你還沒掌握 ElasticSearch Normalizer 的使用方法?

  1. Docs寫入 Elasticsearch時由於 type是 keyword,分詞結果為原始字符串
  2. 查詢 Query 時分詞默認是採用和字段寫時相同的配置,因此這裡也是 keyword,因此分詞結果也是原始字符
  3. 兩邊的分詞進行匹對,便得出了我們上面的結果

2. Normalizer

normalizer是 keyword的一個屬性,可以對 keyword生成的單一 Term再做進一步的處理,比如 lowercase,即做小寫變換。使用方法和自定義分詞器有些類似,需要自定義,如下所示:

DELETE test_normalizer

# 自定義 normalizer

PUT test_normalizer

{

"settings": {

"analysis": {

"normalizer": {

"lowercase": {

"type": "custom",

"filter": [

"lowercase"

]

}

}

}

},

"mappings": {

"doc": {

"properties": {

"type": {

"type": "keyword"

},

"type_normalizer": {

"type": "keyword",

"normalizer": "lowercase"

}

}

}

}

}

PUT test_normalizer/doc/1

{

"type": "apple",

"type_normalizer": "apple"

}

PUT test_normalizer/doc/2

{

"type": "Apple",

"type_normalizer": "Apple"

}

# 查詢三

GET test_normalizer/_search

{

"query": {

"term":{

"type":"aPple"

}

}

}

# 查詢四

GET test_normalizer/_search

{

"query": {

"term":{

"type_normalizer":"aPple"

}

}

}

我們第一步是自定義了名為 lowercase的 normalizer,其中filter 類似自定義分詞器中的 filter ,但是可用的種類很少,詳情大家可以查看官方文檔。然後通過 normalizer屬性設定到字段type_normalizer中,然後插入相同的2條文檔。執行發現,查詢三無結果返回,查詢四返回2條文檔。

問題解決了!我們來看下是如何解決的

聽說你還沒掌握 ElasticSearch Normalizer 的使用方法?

  1. 文檔寫入時由於加入了 normalizer,所有的 term都會被做小寫處理
  2. 查詢時搜索詞同樣採用有 normalizer的配置,因此處理後的 term也是小寫的
  3. 兩邊分詞匹對,就得到了我們上面的結果

3. 總結

本文通過一個實例來給大家講解了 Normalizer的實際使用場景,希望對大家有所幫助!


分享到:


相關文章: