聽說你還沒掌握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,而查詢二沒有文件返回,原因如下圖所示:
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,所有的 term都會被做小寫處理
查詢時搜尋詞同樣採用有 normalizer的配置,因此處理後的 term也是小寫的
兩邊分詞匹對,就得到了我們上面的結果
3. 總結
本文通過一個例項來給大家講解了 Normalizer的實際使用場景,希望對大家有所幫助!
原文釋出時間為:2018-09-10
本文作者: 我的小碗湯
本文來自雲棲社群合作伙伴“ 4GRB7TuTrXDalq85KdHwIgNKmfzrLz1IUJ9mNczLtVLmooQUo*2-QKSpFBoR7PheVOhGm1-D2U3WaGb13DYp2Tba74rDD0C2jZ4W*sp-SYsv1TWUpNkqAVhoUgxgm0hdaWpLB11UCnFbY7pLhhsh28=" target="_blank" rel="nofollow,noindex">我的小碗湯 ”,瞭解相關資訊可以關注“ 我的小碗湯 ”。