這裡我使用elasticsearch官方給的go語言包(go-elasticsearch)
go-elasticsearch向前相容,這意味著客戶端支援與更大或同等次要版本的 Elasticsearch 通訊。Elasticsearch 語言客戶端僅向後相容預設發行版,不提供任何保證。
- 包:https://github.com/elastic/go...
- Elasticsearch 權威指南:https://www.elastic.co/guide/...
環境介紹:
版本
Elasticsearch:v7.15
安裝
go.mod 檔案中新增
require github.com/elastic/go-elasticsearch/v8 main
或者
git clone --branch main https://github.com/elastic/go-elasticsearch.git $GOPATH/src/github.com/elastic/go-elasticsearch
示例:
新建 es.go 存入 es目錄
package es
import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/elastic/go-elasticsearch/v8"
"github.com/elastic/go-elasticsearch/v8/esapi"
"log"
"net/http"
)
var EsClient *elasticsearch.Client
func init() {
cfg := elasticsearch.Config{
Addresses: []string{
"http://localhost:9200",
},
}
var err error
EsClient, err = elasticsearch.NewClient(cfg)
if err != nil {
log.Fatalln("Failed to connect to es")
}
}
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
}
// idx 為空,預設隨機唯一字串
func Index(index, idx string, doc map[string]interface{}) {
//index:="my_index_name_v1"
res, err := EsClient.Info()
fmt.Println(res, err)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
var buf bytes.Buffer
//doc := map[string]interface{}{
// "title": "中國",
// "content": "中國早日統一臺灣",
// "time": time.Now().Unix(),
// "date": time.Now(),
//}
if err = json.NewEncoder(&buf).Encode(doc); err != nil {
fmt.Println(err, "Error encoding doc")
return
}
res, err = EsClient.Index(
index, // Index name
&buf, // Document body
EsClient.Index.WithDocumentID(idx), // Document ID
// Document ID
EsClient.Index.WithRefresh("true"), // Refresh
)
//res, err = EsClient.Create(index, idx, &buf)
if err != nil {
fmt.Println(err, "Error create response")
}
defer res.Body.Close()
fmt.Println(res.String())
log.Println(res)
}
//struct 型別允許使用更實際的方法,您可以在其中建立一個新結構,將請求配置作為欄位,並使用上下文和客戶端作為引數呼叫 Do() 方法:
func IndexEspi(index, idx string, doc map[string]interface{}) {
//index:="my_index_name_v1"
res, err := EsClient.Info()
fmt.Println(res, err)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
var buf bytes.Buffer
//doc := map[string]interface{}{
// "title": "中國",
// "content": "中國早日統一臺灣",
// "time": time.Now().Unix(),
// "date": time.Now(),
//}
if err = json.NewEncoder(&buf).Encode(doc); err != nil {
fmt.Println(err, "Error encoding doc")
return
}
req := esapi.IndexRequest{
Index: index, // Index name
Body: &buf, // Document body
DocumentID: idx, // Document ID
Refresh: "true", // Refresh
}
res, err = req.Do(context.Background(), EsClient)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
defer res.Body.Close()
fmt.Println(res.String())
log.Println(res)
}
func Search(index string, query map[string]interface{}) {
res, err := EsClient.Info()
if err != nil {
fmt.Println(err, "Error getting response")
}
//fmt.Println(res.String())
// search - highlight
var buf bytes.Buffer
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "match": map[string]interface{}{
// "title": title,
// },
// },
// "highlight": map[string]interface{}{
// "pre_tags": []string{"<font color='red'>"},
// "post_tags": []string{"</font>"},
// "fields": map[string]interface{}{
// "title": map[string]interface{}{},
// },
// },
//}
if err := json.NewEncoder(&buf).Encode(query); err != nil {
fmt.Println(err, "Error encoding query")
}
// Perform the search request.
res, err = EsClient.Search(
EsClient.Search.WithContext(context.Background()),
EsClient.Search.WithIndex(index),
EsClient.Search.WithBody(&buf),
EsClient.Search.WithTrackTotalHits(true),
EsClient.Search.WithFrom(0),
EsClient.Search.WithSize(10),
EsClient.Search.WithSort("time:desc"),
EsClient.Search.WithPretty(),
)
if err != nil {
fmt.Println(err, "Error getting response")
}
defer res.Body.Close()
fmt.Println(res.String())
}
//刪除 index 根據 索引名 id
func Delete(index, idx string) {
//index:="my_index_name_v1"
res, err := EsClient.Info()
fmt.Println(res, err)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
res, err = EsClient.Delete(
index, // Index name
idx, // Document ID
EsClient.Delete.WithRefresh("true"),
)
if err != nil {
fmt.Println(err, "Error create response")
}
defer res.Body.Close()
fmt.Println(res.String())
log.Println(res)
}
func DeleteByQuery(index []string, query map[string]interface{}) {
res, err := EsClient.Info()
if err != nil {
fmt.Println(err, "Error getting response")
}
//fmt.Println(res.String())
// search - highlight
var buf bytes.Buffer
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "match": map[string]interface{}{
// "title": title,
// },
// },
// },
//}
if err := json.NewEncoder(&buf).Encode(query); err != nil {
fmt.Println(err, "Error encoding query")
}
// Perform the search request.
res, err = EsClient.DeleteByQuery(
index,
&buf,
)
if err != nil {
fmt.Println(err, "Error getting response")
}
defer res.Body.Close()
fmt.Println(res.String())
}
func SearchEsapiSql(query map[string]interface{}) {
jsonBody, _ := json.Marshal(query)
req := esapi.SQLQueryRequest{Body: bytes.NewReader(jsonBody)}
res, _ := req.Do(context.Background(), EsClient)
defer res.Body.Close()
fmt.Println(res.String())
}
func SearchHttp(method, url string, query map[string]interface{}) {
jsonBody, _ := json.Marshal(query)
req, _ := http.NewRequest(method, url, bytes.NewReader(jsonBody))
req.Header.Add("Content-type", "application/json")
res, err := EsClient.Perform(req)
if err != nil {
return
}
defer res.Body.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(res.Body)
fmt.Println(buf.String())
}
新建 main.go
package main
import "demo/es"
func main() {
index := "my_index_name_v4"
//建立索引並設定對映
//query := map[string]interface{}{
// "mappings": map[string]interface{}{
// "properties": map[string]interface{}{
// "title": map[string]interface{}{
// "type": "text",
// },
// "content": map[string]interface{}{
// "type": "text",
// },
// "location": map[string]interface{}{
// "type": "geo_point",
// },
// "time": map[string]interface{}{
// "type": "long",
// },
// "date": map[string]interface{}{
// "type": "date",
// },
// "age": map[string]interface{}{
// "type": "keyword",
// },
// },
// },
//}
//url := index
//注意 對映資訊不能更新
//es.SearchHttp("PUT", url, query)
//新增或修改文件,沒有索引建立
//doc := map[string]interface{}{
// "title": "你好",
// "content": "中國美麗的城市",
// "location": "41.015, -75.011",
// "time": time.Now().Unix(),
// "date": time.Now(),
// "age": 20,
//}
//es.Index(index, "", doc)
//es.IndexEspi(index, "idx5", doc)
//刪除索引
//es.Delete(index, "idx3")
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "match": map[string]interface{}{
// "title": "vvvvv我愛你!!!!",
// },
// },
//}
//indexArr := []string{index}
//es.DeleteByQuery(indexArr, query)
////搜尋單個欄位
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "match": map[string]interface{}{
// "title": "我愛你中國",
// },
// },
// "highlight": map[string]interface{}{
// "pre_tags": []string{"<font color='red'>"},
// "post_tags": []string{"</font>"},
// "fields": map[string]interface{}{
// "title": map[string]interface{}{},
// },
// },
//}
//搜尋多個欄位
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "multi_match": map[string]interface{}{
// "query": "中國",
// "fields": []string{"title", "content"},
// },
// },
// "highlight": map[string]interface{}{
// "pre_tags": []string{"<font color='red'>"},
// "post_tags": []string{"</font>"},
// "fields": map[string]interface{}{
// "title": map[string]interface{}{},
// },
// },
//}
//提高某個欄位權重,可以使用 ^ 字元語法為單個欄位提升權重,在欄位名稱的末尾新增 ^boost ,其中 boost 是一個浮點數:
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "multi_match": map[string]interface{}{
// "query": "中國",
// "fields": []string{"title", "content^2"},
// },
// },
// "highlight": map[string]interface{}{
// "pre_tags": []string{"<font color='red'>"},
// "post_tags": []string{"</font>"},
// "fields": map[string]interface{}{
// "title": map[string]interface{}{},
// },
// },
//}
//顯示所有的
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "match_all": map[string]interface{}{},
// },
//}
//es.Search(index, query)
//地理距離過濾器( geo_distance )以給定位置為圓心畫一個圓,來找出那些地理座標落在其中的文件:
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "bool": map[string]interface{}{
// "must": map[string]interface{}{
// "match_all": map[string]interface{}{}, // 這裡不設定其他查詢條件,所以匹配全部文件
// },
// "filter": map[string]interface{}{
// "geo_distance": map[string]interface{}{
// "distance": "100km",
// "location": map[string]interface{}{
// "lat": 40.715,
// "lon": -73.988,
// },
// }},
// },
// },
// "sort": map[string]interface{}{ // 設定排序條件
// "_geo_distance": map[string]interface{}{ //_geo_distance代表根據距離排序
// "location": map[string]interface{}{ //根據location儲存的經緯度計算距離。
// "lat": 40.715, //當前緯度
// "lon": -73.988, //當前經度
// },
// "order": "asc", // asc 表示升序,desc 表示降序
// }},
//}
//es.Search(index, query)
//精確值查詢
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "match": map[string]interface{}{
// "age": "20",
// },
// },
//}
//es.Search(index, query)
//範圍查詢
//通過range實現範圍查詢,類似SQL語句中的>, >=, <, <=表示式。
//gte範圍引數 - 等價於>=
//lte範圍引數 - 等價於 <=
//範圍引數可以只寫一個,例如:僅保留 "gte": 10, 則代表 FIELD欄位 >= 10
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "range": map[string]interface{}{
// "age": map[string]interface{}{
// "gte": "19",
// "lte": "20",
// },
// },
// },
//}
//es.Search(index, query)
//組合查詢 如果需要編寫類似SQL的Where語句,組合多個欄位的查詢條件,可以使用bool語句。
//"must": [], // must條件,類似SQL中的and, 代表必須匹配條件
//"must_not": [], // must_not條件,跟must相反,必須不匹配條件
//"should": [] // should條件,類似SQL中or, 代表匹配其中一個條件
query := map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
{
"match": map[string]interface{}{
"age": "19",
},
},
{
"match": map[string]interface{}{
"title": "中國",
},
},
},
},
},
}
es.Search(index, query)
//使用mysql的方式來請求
//query := map[string]interface{}{
// "query": "select title from " + index + " where title like '%中國%'", //這裡使用mysql的方式來請求,非常簡單,符合開發習慣,簡化es入門門檻,支援order,支援Limit,那麼排序和分頁就自己寫好了
//}
//query := map[string]interface{}{
// "query": "select title from " + index + " where title = '中國'", //這裡使用mysql的方式來請求,非常簡單,符合開發習慣,簡化es入門門檻,支援order,支援Limit,那麼排序和分頁就自己寫好了
//}
//es.SearchEsapiSql(query)
//測試分詞
//query := map[string]interface{}{
// "analyzer": "ik_smart", //智慧分詞用:ik_smart,最大化分詞用:ik_max_word
// "text": "中國華人民",
//}
//url := index + "_analyze?pretty=true"
//query := map[string]interface{}{
// "query": map[string]interface{}{
// "match": map[string]interface{}{
// "title": "我愛你中國",
// },
// },
// "highlight": map[string]interface{}{
// "pre_tags": []string{"<font color='red'>"},
// "post_tags": []string{"</font>"},
// "fields": map[string]interface{}{
// "title": map[string]interface{}{},
// },
// },
//}
//url := index + "/_search"
//es.SearchHttp("GET", url, query)
}
參考資料
https://github.com/elastic/go...
https://www.tizi365.com/archi...
https://www.elastic.co/guide/...
links
- 目錄
- 上一節:
- 下一節: