1. 程式人生 > >ES 對各欄位建立分詞 和mapping建立 個人操作記錄

ES 對各欄位建立分詞 和mapping建立 個人操作記錄

最近在搞es的查詢和,需要使用到模糊查詢 匹配

在之前使用的時候,java 中的String 在 es 預設建立的mapping type是 String 是可以模糊查詢的 ,但是新版的ES 廢棄了 string 變為  text 和 keyword

這樣一來 不管是 trem 還是 fuzzy 查詢都不能查詢 (也有可能是我個人寫法問題,後續在研究下)

一開始想法很天真 很簡單 就想修改es 的mapping ,比如我的其中一個欄位 title ES預設建立的mapping 是如下格式

使用 -XGET http://192.168.136.128:9200/motor_fans_short_topic/_mapping?pretty

檢視 新建的 index 的mapping

title" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },

就很天真的通過 curl 將 title 修改為 text :String

curl -XPOST "http://192.168.136.128:9200/motor_fans_short_topic/motor_fans_short_topic/_mapping?pretty" -d '{
     "motor_fans_short_topic": {
        "properties": {
             "title":{
                "type":"string"
           }
        }
    }
    }'

很可惜 不支援 POST 直接報錯 (吐槽下 安裝的crul 很坑爹 ,真想打死公司的運維 什麼都有問題 這只是第一個問題)

修改 put  很可惜 還是報錯  405  是 不支援 大概意思是 確實 請求 head  坑爹吧 這不是預設的嗎 好吧 加引數

-H "Content-Type:application/json"

curl -XPUT  "http://192.168.136.128:9200/motor_fans_short_topic/motor_fans_short_topic/_mapping?pretty"   -H "Content-Type:application/json" -d '{
     "motor_fans_short_topic": {
        "properties": {
             "title":{
                "type":"string"
           }
        }
    }
    }'

不好意思 還錯,查了下 Elasticsearch的 mapping 一旦新建 只能新增欄位 不能修改,其實想想馬上理解,人家都分詞什麼的做好,你突然修改人家之前的工作都白做了,要你你樂意

所以到此 對於新接觸的我來說 有點懵了,預設新建的不能使用不符合業務需求,預設新建的不能修改,有無法使用post 建立 index (其實是可以的,我的錯)

到此我就覺得是時候安裝 IK 了 ,所以 開始安裝 IK 分詞了

IK 的分詞很簡單,參照官網安裝就可以了  https://github.com/medcl/elasticsearch-analysis-ik

安裝好之後 測試,發現中文分詞就是有問題,是編碼問題,也不想修改別人的系統,找替代

我刪除了所有我在ES中建立的現有 index

curl -XDELETE 'http://192.168.136.128:9200/motor_fans_short*'

請慎用 很有威力

我覺得放棄使用 crul  使用 psotman 操作


建立成功 很好,

如果index 不存在 使用如下方式 在建立 index 的 同時 建立 mapping

之後建立 對應的mapping :


http://192.168.136.128:9200/motor_fans_short_topic

{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "ik" : {
                    "tokenizer" : "ik_max_word"
                }
            }
        }
    },
    "mappings" : {
        "motor_fans_short_topic" : {
            "dynamic" : true,
            "properties" : {
                  "intro" :
                  {    "type": "text",
                    "analyzer": "ik_max_word",
                    "search_analyzer": "ik_max_word"
                  },
                "title" : {
                    "type": "text",
                    "analyzer": "ik_max_word",
                    "search_analyzer": "ik_max_word"
                }
            }
        }
    }
}

只想修改了title 和 intro的預設 匹配 ,所有 值建立對應的,其他欄位採用預設mapping  建立成功

如果 已經建立 index  則使用如下方式:


http://192.168.136.128:9200/motor_fans_short_topic/motor_fans_short_topic/_mapping

{
    "properties" : {
          "intro" :
          {    "type": "text",
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word"
          },
        "title" : {
            "type": "text",
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word"
        }
    }
}

注意兩者的區別,其實一樣,只是主要mapping 建立好之後只能 新增欄位 不能修改已經有的欄位

之後 使用 已有的 API 介面往ES中插入資料  重新 檢視 mapping

title 和 intro 都是設定預設。

再次使用term 查詢 查詢成功。目前 業務 提供jar 講資料寫入 kafka ,kafka consumer端寫入es 分詞完成,模糊查詢完成

剩下還有一項工作,就是要將歷史資料匯入ES 中

有三種方案 :

第一種:寫程式,連結MYSQL,批量的寫入kakfa中,後續在現有邏輯已經完成,可以好low啊 而且麻煩

第二種:使用kafka的connect 從 mysql 匯入 kafka ,kafka的consumer 程式寫入ES中

第二種:直接從資料庫中寫入 ES中,最直接 最省事

尋找從MYSQL寫入ES的方案。使用另外一篇記錄遇到的坑吧