天天看點

Elasticsearch 6.3.2版本踩填坑指南

前言

  前端時間利用ES開發一個"附近地理位置+其它資訊"查詢搜尋的功能(據了解,Redis和PostgreSQL也能實作同樣的功能),實踐中遇到了不少的問題,是以通過這篇文章記錄下踩填坑過程。

es with docker

  個人喜好,一般使用中間件都喜歡用Docker運作較新版本的,用

docker pull elasticsearch

指令拉下來的版本一般不會是最新的,是以可以從

這裡

找到最新版本的拉取指令,稍加改造後我需要的是這樣的:

docker run --name elasticsearch -e "ES_JAVA_OPTS=-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.2

  注意到這裡指定的鏡像是

elasticsearch-oss:6.3.2

,這個

-oss

表示不包括

X-Pack

的ES鏡像,這也是在6.0+版本後劃分的,剩下兩種類型是

basic

(預設)和

platinum

,具體官方說明可以看下圖。

Elasticsearch 6.3.2版本踩填坑指南

Elasticsearch Docker Image Types

  如果啟動失敗,使用指令

docker logs elasticsearch

檢視日志即可,

-f

參數用于監聽,其中一種啟動錯誤是要求你修改

vm.max_map_count

這個系統環境參數,Linux可參考指令

sysctl -w vm.max_map_count=262144

設定即可(其它系統在文末官方參考連結中有更詳細介紹)。

create mapping

  這部分是重點,之前遇到的坑就是type mapping這塊。

  1. "_id is not configurable"

  es2.0+版本中,

_id

是可以配置的,網上也有一堆告訴你怎麼設定,但es6.3.2中建立mapping并指定

_id

配置的時候,es傳回錯誤中就出現了上面那句,在社群可以找到了這個

Discuss

。高版本中的

_id

是不能配置了,一般來說,在添加Document的時候,如果隻指定Index和Document Type,那麼es會随機給這個

_id

配置設定一個值,但如果添加的時候指定這個

_id

值,那麼ES就不會再随機配置設定這個值。不過注意,即使你指定的

_id

是一個數值,但在實際儲存和傳回中都是字元串類型;

  1. "Mapping with Index not_analyzed is not working"

  這個問題在Github上也有相關的

Issues

,我在這裡先還原下當初建立mapping的配置:

{
    "properties": {
        # 當初的想法是指定shopId這個字段不要分析,然後keyword字段要進行分析
        "shopId": {
          "type": "integer",
          "index": "not_analyzed"
        },
        "location": {
          "type": "geo_point"
        },
        "keyword":{
          "type": "text",
          "index": "analyzed",
          "analyzer": "ik_max_word"
        }
    }
}
           

  建立完上述mapping後通路

http://localhost:9200/{index}/{type}/_mapping

,但傳回結果(如下)和上面指定的mapping并不相同:

{
    "{index}": {
        "mappings": {
            "{type}": {
                "properties": {
                    "shopId": {
                        "type": "integer"
                    },
                    "location": {
                        "type": "geo_point"
                    },
                    "keyword": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    },
                }
            }
        }
    }
}
           

  之後還是在官方文檔中找到答案,發現确實有兩點值得記錄一下。

  • 第一點:es5.0之後,為字元串新增了

    keyword

    類型,而之前的版本中隻有

    text

    類型,通過index屬性判斷是否需要分詞(預設分詞)。es5.0之後使用keyword type代替index這個屬性,是以指定

    "type": "text"

    就是分詞,指定

    "type": "keyword"

    就是不分詞;
  • 第二點:不需要為type為數字類型integer、long,日期類型date、布爾類型boolean等指定

    "index": "not_analyzed"

    屬性(而且在高版本es中這也是錯誤的文法,index隻能指定為

    "index": true | false

    ,false意味着不可查詢),因為這些類型就是不分詞的,如果要分詞請修改為text類型。

ik analysis

  IK是國内用得比較多的中文分詞器,與ES安裝內建也比較簡單,首先進入docker

docker exec -it elasticsearch bash

,然後用指令

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.2/elasticsearch-analysis-ik-6.3.2.zip

安裝即可(需對應es版本),安裝完使用

docker restart elasticsearch

重新開機服務即可。IK支援兩種分詞方式,

ik_smart

ik_max_word

,前者分詞粒度沒有後者細,可以針對實際情況進行選擇。

head plugin

  elasticsearch-head插件也是測試的時候用得比較多的插件,以前用ES2的時候是借助plugin腳本安裝的,但這種方式在ES5.0之後被廢棄了,然後作者也推薦了好幾種方式,可以借助npm運作該服務,或者用docker運作服務,不過為了簡單起見我最後選的是

Chrome extension

這種方式。

參考連結

Install Elasticsearch with Docker Mapping Text datatype Keyword datatype how-to-not-analyze-in-elasticsearch elasticsearch-analysis-ik elasticsearch-head

繼續閱讀