本文首發於我的個人博客
這是一篇介紹如何利用golang第三方庫https://github.com/olivere/elastic進行elasticsearch的操作的文章。
文章中並不會介紹非常詳細的API,更側重於作者在工作中的使用經驗和查文檔經驗。文章中主要包括以下內容:
- 作者認爲比較重要的API設計理念以及文檔查閱方式
- 作者在工作中使用到的elasticsearch的實例,包括從接到需求,查閱文檔,並實現的過程
API設計理念思考
API的分類
在使用elasticsearch的golang Client過程中,我覺得可以將olivere/elastic的常用API分作三類:
- 面向elasticsearch的metadata的Service
- 面向elasticsearch的data的Service
- 面向Query
而這三類分別對應了對elasticsearch的不同類別的操作:
- 面向elasticsearch的metadata的Service,主要是對elasticsearch的metadata進行查詢和操作,比如
- 配置elasticsearch
- 查詢elasticsearch的狀態,比如集羣狀態,節點數目等
- 面向elasticsearch的data的Service,住喲是對elasticsearch內的數據和數據格式進行操作
- elasticsearch中的index的metadata進行操作,比如
- 查詢是否存在某個index
- 創建並配置index
- elasticsearch中的index下的document的增刪改操作
- elasticsearch中的index的metadata進行操作,比如
- 面向Query,主要是對index下的document的查詢操作
分類在代碼中的體現
首先需要說明,在olivere/elastic的所有操作都是依靠生成一個XXXService
對象然後XXXService.Do(ctx)
來實現的,這裏將他們分成面向Service和麪向Query只是表示後者我們的主要精力都會集中在構造Query上
面向elasticsearch的metadata的Service
面向elasticsearch的metadata的Service,一般是通過建立連接的ESClient,新建出查詢或者操作所需的Service,而後進行操作的模式
比如如下,查詢集羣內es節點數
// 建立連接的Client
esClient, _ := elastic.NewClient()
// 新建出用於操作的Service
clusterHealthClient := elastic.NewClusterHealthService(esClient)
// 查詢,拿到結果
result, _:= clusterHealthClient.Do(context.Background())
fmt.Println(result.NumberOfNodes)
面向elasticsearch的data的Service
面向elasticsearch的data的Service,一般是通過建立連接的ESClient的成員函數直接取得Service,而後進行操作
比如如下,新建索引
// Create a new index.
mapping := `{
"settings":{
"number_of_shards":1,
"number_of_replicas":0
},
"mappings":{
"properties":{
"tags":{
"type":"keyword"
},
"location":{
"type":"geo_point"
},
"suggest_field":{
"type":"completion"
}
}
}
}`
ctx := context.Background()
createIndex, _ := esClient.CreateIndex("twitter").BodyString(mapping).Do(ctx)
fmt.Println(createIndex.Index)
面向Query
面向Query,一般是先新建出Query,而後通過client.Search().Index(index).Query(query).Do(ctx)
的方式執行查詢操作
比如如下,查詢上一個構造的索引中,tags
字段含有test
的document
query := elastic.NewBoolQuery()
query = query.Must(elastic.NewTermQuery("tags", "test"))
result, _ := esClient.Search().Index("twitter").Query(query).Do(context.Background())
API文檔的查詢方法
查詢olivere/elastic的文檔,主要有三個來源:
- 項目Wiki https://github.com/olivere/elastic/wiki
- 源代碼 https://github.com/olivere/elastic
- elasticsearch官方文檔 https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
這三者各有特點:
- 項目Wiki
- 優點:簡單直接,並且會給出相應的操作的示例代碼,上手很快
- 缺點:示例較簡單,且不全面,面對複雜邏輯/特定邏輯很可能缺乏指導性,或者找不到相關文檔
- 源代碼
- 優點:全面而且本質的東西,掌握了源代碼就掌握了一切
- 缺點:複雜,費力,考慮投入產出比,幾乎絕無必要源碼級掌握(除非想成爲庫的開發者)
- elasticsearch官方文檔
- 優點:比較齊全的同時仍然是可讀性較高的文檔,難度在項目Wiki和源代碼之間
- 缺點:沒有直接對應到olivere/elastic的API上,找到elasticsearch的API之後,要回頭再找olivere/elastic的API
一般的查詢方式如下:
- 首先明確需求,即到底需要獲得elasticsearch的什麼信息或者對其進行什麼操作
- 明確需求後先查閱Wiki,如果有相應的條目,可用的就可以直接用了
- Wiki中找不到,那就按照api設計理念思考中描述的進行分類
- 分類後有兩條路徑
- 源代碼中尋找對應的Service或者Query接口,找到後去elasticsearch文檔驗證
- elasticsearch文檔中尋找對應的查詢接口,找到後去olivere/elastic中找對應的接口
當然,合理利用其他資源作爲文檔入口也是有必要的(或許這纔是很多人的首選):
- Stack Overflow,啓動!
- 輸入關鍵字查詢,能找到合適的問答,就直接採用,不能就返回上述的一般查詢方式
使用實例與解決過程
查詢集羣的健康狀態
過程:
- 查閱Wiki,沒有
- 查閱源代碼,cluster爲關鍵字查找,找到cluster_health.go,前往註釋中指定的elasticsearch文檔http://www.elastic.co/guide/en/elasticsearch/reference/7.0/cluster-health.html驗證想法
- 想法驗證成功,編程
實現text類型的字段的模糊查找
過程:
- 查找Wiki,沒有
- 源代碼,elasticsearch文檔沒有“模糊查找”相關的部分
- stack overflow 搜索 match part of text,找到使用正則表達式查詢RegexQuery的方法
- 返回elasticsearch文檔驗證,驗證成功