天天看點

聽說你還沒掌握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,而查詢二沒有文檔傳回,原因如下圖所示:

聽說你還沒掌握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條文檔。

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

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

文檔寫入時由于加入了 normalizer,所有的 term都會被做小寫處理

查詢時搜尋詞同樣采用有 normalizer的配置,是以處理後的 term也是小寫的

兩邊分詞匹對,就得到了我們上面的結果

3. 總結

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

原文釋出時間為:2018-09-10

本文作者:

我的小碗湯

本文來自雲栖社群合作夥伴“

的小碗湯

”,了解相關資訊可以關注“

”。

繼續閱讀