1. 程式人生 > >ElasticSearch搜尋時match和term大小寫問題

ElasticSearch搜尋時match和term大小寫問題

ES的建立索引過程:分詞->語法處理(還原時態等等)->排序->建立索引。

其他暫不討論,本文只討論大小寫問題。

如果建立index時mapping沒有指定某個filed的標準化配置normalizer,那麼如果寫入ES的是大寫,搜尋出來看到的結果也是大寫,但是建立的索引卻是小寫(可以用分詞驗證),以至於搜尋的時候使用term會失敗。

比如我的mapping為(內部使用,非完整mapping,重要是看欄位):

"mappings": {
          "rack_crm_community_type": {
            "dynamic": "false",
            "_all": {
              "enabled": false
            },
            "properties": {
              "claimBdPin": {
                "type": "string"
              },
              "createBdPin": {
                "type": "string"
              },
              "city": {
                "type": "integer"
              },
              "communityStatusCode": {
                "type": "integer"
              },
              "communityName": {
                "analyzer": "ik_max_word",
                "type": "string"
              },
              "location": {
                "type": "geo_point"
              },
              "communityId": {
                "type": "long"
              },
              "communityPersonNum": {
                "type": "integer"
              },
              "claimTime": {
                "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
                "type": "date"
              }
            }
          }
        }

 以"claimBdPin"欄位為例,只是指定了String型別。儲存結果為:

當搜尋條件為:

{
  "query":{
    "bool":{
      "filter":[
        {"term":  {"claimBdPin":"KA_liulin"}}
      ]
    }
  }
}
結果為空。

當搜尋條件為:

{
  "query":{
    "bool":{
      "must":[
        {"match":  {"claimBdPin":"KA_liulin"}}
      ]
    }
  }
}

結果為:

能查詢到,為什麼呢?測試分詞(ik_max_word)發現:KA_liulin分詞為ka_liulin、ka、liulin三個分詞。雖然儲存的是KA_liulin,但是因為建立索引的時候會自動進行處理為ka_liulin(因為mapping未做分詞),再建立索引。match查詢的時候,會自動對引數進行處理,所以match搜尋的時候使用KA_liulin(實際搜尋為ka_liulin)能查詢到,而term則查詢不到。

因為mapping時未設定分詞,所以一般使用term(過濾)來查詢,所以要麼在程式碼裡面使用String.toLowerCase,但是太麻煩,那麼要怎麼一次性解決問題呢?我們可以mapping的時候設定normalizer(normalizer用於解析前的標準化配置,比如把所有的字元轉化為小寫等)

PUT index
{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "type": {
      "properties": {
        "foo": {
          "type": "keyword",
          "normalizer": "my_normalizer"
        }
      }
    }
  }
}