概述
Elasticsearch 與傳統的 SQL資料庫的一個明顯的不同點是,Elasticsearch 是一個 非結構化 的資料庫,或者說是一個 無模式 的資料庫。Elasticsearch 中資料最重要的三要素當屬:索引、型別、文件,其中索引這個概念非常重要,我們可以粗略地將其類比到傳統SQL資料庫中的 資料表。本文就從 Elasticsearch 的索引對映如何配置開始講起。
注: 本文首發於 My Personal Blog,歡迎光臨 小站 !
本文內容腦圖如下:文章共1540字,閱讀本文大約需要5分鐘 !
索引模式對映
建立索引時,可以自定義索引的結構,比如 建立一個儲存使用者資訊資料的 users
索引,其典型的結構如下:
id
:唯一表示符name
:姓名birthday
:出生日期hobby
:愛好
為此我們可以建立一個 json 格式的索引模式對映檔案:users.json
{
"mappings" : {
"user" : {
"properties" : {
"id" : {
"type" : "long",
"store" : "yes"
},
"name" : {
"type" : "string",
"store" : "yes",
"index" : "analyzed"
},
"birthday" : {
"type" : "date",
"store" : "yes"
},
"hobby" : {
"type" : "string",
"store" : "no",
"index" : "analyzed"
}
}
}
}
}
複製程式碼
上面的 json程式碼意義如下:
- 建立一個名稱為
users
的 Index - 裡面有一個名稱為
user
的 Type - 而
user
有四個 field - 且每個 field 都有自己的 屬性 定義
然後我們來執行如下命令來新建一個索引:
curl -X PUT http://47.98.43.236:9200/users -d @users.json
複製程式碼
結果如下,索引 users
、型別 user
、以及 四個欄位 都已經順利插入:
關於欄位的 可選型別,有如下幾種:
string
:字串number
:數字date
:日期boolean
:布林型binary
:二進位制ip
:IP地址token_count
型別
關於每種型別有哪些 屬性,可參考官方文件,由於內容太多,此處不再贅述。
分析器的使用
分析器是一種用於 分析資料 或者按照使用者想要的方式 處理資料 的工具,對於 字串型別 的欄位,Elasticsearch 允許使用者自定義分析器。
- 先來自定義一個分析器
{
"settings" : {
"index" : {
"analysis" : {
"analyzer" : {
"myanalyzer" : {
"tokenizer" : "standard",
"filter" : [
"asciifolding",
"lowercase",
"myFilter"
]
}
},
"filter" : {
"myFilter" : {
"type" : "kstem"
}
}
}
}
},
"mappings" : {
"user" : {
"properties" : {
"id" : {
"type" : "long",
"store" : "yes"
},
"name" : {
"type" : "string",
"store" : "yes",
"index" : "analyzed",
"analyzer" : "myanalyzer"
},
"birthday" : {
"type" : "date",
"store" : "yes"
},
"hobby" : {
"type" : "string",
"store" : "no",
"index" : "analyzed"
}
}
}
}
}
複製程式碼
上述 json程式碼中,使用者定義了一個名為 myanalyzer 的分析器,該分析器包含 一個分詞器 + 三個過濾器,分別如下:
- 分詞器:
standard
- 過濾器:
asciifolding
- 過濾器:
lowercase
- 過濾器:
myFilter
(自定義過濾器,其本質是kstem
)
- 再來看如何測試和使用自定義的分析器
可以通過類似如下的 Restful介面來測試 analyze API 的工作情況:
curl -X GET 'http://47.98.43.236:9200/users/_analyze?field=user.name' -d 'Cars Trains'
複製程式碼
可見我們輸入的時一行字串普通"Cars Trains"
,而輸出為:car
和 train
,這說明短語 "Cars Trains"
被分成了兩個詞條,然後全部轉為小寫,最後做了詞幹提取的操作,由此證明我們上面自定義的分析器已然生效了!
相似度模型的配置
Elasticsearch 允許為索引模式對映檔案中的不同欄位指定不同的 相似度得分 計算模型,其用法例析如下:
"mappings" : {
"user" : {
"properties" : {
"id" : {
"type" : "long",
"store" : "yes"
},
"name" : {
"type" : "string",
"store" : "yes",
"index" : "analyzed",
"analyzer" : "myanalyzer",
"similarity" : "BM25"
},
"birthday" : {
"type" : "date",
"store" : "yes"
},
"hobby" : {
"type" : "string",
"store" : "no",
"index" : "analyzed"
}
}
}
}
複製程式碼
上述 json檔案中,我們為
name
欄位使用了BM25
這種相似度模型,新增的方法是使用similarity
屬性的鍵值對,這樣一來 Elasticsearch 將會為name
欄位使用BM25
相似度計算模型來計算相似得分。
資訊格式的配置
Elasticsearch 支援為每個欄位指定資訊格式,以滿足通過改變欄位被索引的方式來提高效能的條件。Elasticsearch 中的資訊格式有如下幾個:
default
:預設資訊格式,其提供了實時的對儲存欄位和詞向量的壓縮pulsing
:將 重複值較少欄位 的資訊列表 編碼為詞條矩陣,可加快 該欄位的查詢速度direct
:該格式在讀過程中將詞條載入到未經壓縮而存在記憶體的矩陣中,該格式可以提升常用欄位的效能,但損耗記憶體memory
:該格式將所有的資料寫到磁碟,然後需要FST來讀取詞條和資訊列表到記憶體中bloom_default
:預設資訊格式的擴充套件,增加了把bloom filter
寫入磁碟的功能。讀取時bloom filter
被讀取並存入記憶體,以便快速檢查給定的值是否存在bloom_pulsing
:pulsing
格式的擴充套件,也加入bloom filter
的支援
資訊格式欄位(postings_format
)可以在 任何一個欄位上 進行設定,配置資訊格式的示例如下:
"mappings" : {
"user" : {
"properties" : {
"id" : {
"type" : "long",
"store" : "yes",
"postings_format" : "pulsing"
},
"name" : {
"type" : "string",
"store" : "yes",
"index" : "analyzed",
"analyzer" : "myanalyzer"
},
"birthday" : {
"type" : "date",
"store" : "yes"
},
"hobby" : {
"type" : "string",
"store" : "no",
"index" : "analyzed"
}
}
}
}
複製程式碼
在該例子之中,我們手動配置改變了
id
欄位的資訊格式為pulsing
,因此可加快該欄位的查詢速度。
文件值及其格式的配置
文件值 這個欄位屬性作用在於:其允許將給定欄位的值被寫入一個更高記憶體效率的結構,以便進行更加高效的排序和搜尋。我們通常可以將該屬性加在 需要進行排序 的欄位上,這樣可以 提效。
其配置方式是 通過屬性 doc_values_format
進行,有三種常用的 doc_values_format
屬性值,其含義從名字中也能猜個大概:
default
:預設格式,其使用少量的記憶體但效能也不錯disk
:將資料存入磁碟,幾乎無需記憶體memory
:將資料存入記憶體
舉個栗子吧:
"mappings" : {
"user" : {
"properties" : {
"id" : {
"type" : "long",
"store" : "yes"
},
"name" : {
"type" : "string",
"store" : "yes",
"index" : "analyzed",
"analyzer" : "myanalyzer"
},
"birthday" : {
"type" : "date",
"store" : "yes"
},
"hobby" : {
"type" : "string",
"store" : "no",
"index" : "analyzed"
},
"age" : {
"type" : "integer",
"doc_values_format" : "memory"
}
}
}
}
複製程式碼
上述 json配置中,我們給型別
user
新增了一個age
欄位,假如我們想對年齡欄位進行排序,那麼給該欄位設定文件值格式的屬性是可以提升效率的。
後 記
由於能力有限,若有錯誤或者不當之處,還請大家批評指正,一起學習交流!
可 長按 或 掃描 下面的 小心心 來訂閱 CodeSheep,獲取更多 務實、能看懂、可復現的 原創文 ↓↓↓