Elasticsearch讓 keyword 和 term 忽略大小寫

在 Elasticsearch 中處理字符串類型的數據時,如果我們想把整個數據作爲一個完整的 term 存儲,我們通常會將其類型( type) 設定爲 keyword。而這種設定又會給我們帶來麻煩,比如 Barbar兩個實際都是 bar,但當我們去搜索 bar時卻無法返回 Bar的文檔。要解決這個問題,就需要 Normalizer出場了!

 


PUT test_normalizer
{
  "mappings": {
    "properties": {
        "foo":{
          "type":"keyword"
        }
      }
  }
}

PUT test_normalizer/_doc/1
{
  "foo":"bar"
}

PUT test_normalizer/_doc/2
{
  "foo":"Bar"
}


# 查詢一 
GET test_normalizer/_search
{
  "query": {
    "match":{
      "foo":"bar"
    }
  }
}

# 查詢二
GET test_normalizer/_search
{
  "query": {
    "match":{
      "foo":"BAr"
    }
  }
}
# 查詢三
GET test_normalizer/_search
{
  "query": {
    "term":{
      "foo":"baR"
    }
  }
}

結果:

查詢一:返回 id=1的數據

查詢二、查詢三:查詢不到數據

原因:

  1. 寫入 Elasticsearch時由於字段的 type是 keyword,分詞結果爲原始字符串(type=string時,是轉爲小寫創建索引的)

  2. 查詢 Query 時分詞默認是採用和字段寫時相同的配置,因此這裏也就是 keyword,這查就是直接把內容去匹配了;從而查詢一可以匹配到數據,查詢二、三查詢不到數據;

  3. 注意:term是代表完全匹配,即查詢的關鍵詞不會被分詞處理;

 

解決方案:Normalizer


DELETE test_normalizer
# 自定義 normalizer

PUT test_normalizer
{
  "settings": {
    "analysis": {
      "normalizer": {
        "lowercase": {
          "type": "custom",
          "filter": ["lowercase"]
        }
      }
    }
  },
  "mappings": {
      "properties": {
        "foo": {
          "type": "keyword"
        },
        "foo_normalizer": {
          "type": "keyword",
          "normalizer": "lowercase"
        }
    }
  }
}

PUT test_normalizer/_doc/1
{
  "foo": "bar",
  "foo_normalizer": "bar"
}
PUT test_normalizer/_doc/2
{
  "foo": "Bar",
  "foo_normalizer": "Bar"
}

# 查詢三
GET test_normalizer/_search
{
  "query": {
    "term":{
      "foo":"BaR"
    }
  }
}
# 查詢四
GET test_normalizer/_search
{
  "query": {
    "term":{
      "foo_normalizer":"bAr"
    }
  }
}

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

2、我們第一步是自定義了名爲 lowercase的 normalizer,其中filter 類似自定義分詞器中的 filter ,normalizer中可可用的filtr種類很少,詳情大家可以查看官方文檔。

3、通過 normalizer屬性設定到指定字段type_normalizer中;

4、然後插入相同的2條文檔。執行發現,查詢三無結果返回,查詢四返回2條文檔。

 

流程說明:

  1. es文檔寫入時由於對字段指定了 normalizer,那該字段的 term都會被做小寫處理

  2. 查詢時搜索詞同樣採用有 normalizer的配置,因此處理後的 term也是小寫的

  3. 這樣寫入數據和搜索都忽略大小寫,就得到了我們上面的結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章