Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(es): add elasticsearch client(v7) #95

Merged
merged 3 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Changelog

## v1.7.1
- feat(es): add elasticsearch client(v7)
- chore(cli): approve gen task command
- chore(response): remove init resp and improve Error
- chore(server): improve consumer server
Expand Down
9 changes: 2 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,8 @@ lint:

.PHONY: test
# make test
test: test-case vet
@go test -short ${PKG_LIST} -tags test

.PHONY: test-case
# make test-case
test-case:
@go test -cover ./... | grep -v vendor;true
test:
@go test -short ${PKG_LIST} | grep -v examples

.PHONY: vet
# make vet
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/eapache/go-resiliency v1.1.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/elastic/go-elasticsearch/v7 v7.17.10
github.com/foolin/gin-template v0.0.0-20190415034731-41efedfb393b
github.com/frankban/quicktest v1.7.2 // indirect
github.com/fsnotify/fsnotify v1.5.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/elastic/go-elasticsearch/v7 v7.17.10 h1:TCQ8i4PmIJuBunvBS6bwT2ybzVFxxUhhltAs3Gyu1yo=
github.com/elastic/go-elasticsearch/v7 v7.17.10/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
Expand Down
10 changes: 9 additions & 1 deletion pkg/storage/elasticsearch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ Elasticsearch 是当前比较流行的 搜索框架,这里提供两个库,
- 官方 [https://github.com/elastic/go-elasticsearch](https://github.com/elastic/go-elasticsearch) star: 2700+
- 第三方[https://github.com/olivere/elastic](https://github.com/olivere/elastic) star: 5300+

> 第三方的这个已经不在维护,所以推荐使用官方的

## Compatibility

The client major versions correspond to the compatible Elasticsearch major versions: to connect to Elasticsearch 7.x,
use a 7.x version of the client, to connect to Elasticsearch 6.x, use a 6.x version of the client.

## Reference

- https://medium.com/a-journey-with-go/go-elasticsearch-clients-study-case-dbaee1e02c7
- https://mp.weixin.qq.com/s?__biz=MzkyNzI1NzM5NQ==&mid=2247484756&idx=1&sn=6029ed72391e175ebef3de47bf9290a2&chksm=c22b8308f55c0a1eb0d06f4f5f7404e0ba33f6bb10a86f996dfbbd7b80b952e5bef97ce2344f&cur_album_id=1932372564102709257&scene=189#wechat_redirect
- https://discuss.elastic.co/t/go-elasticsearch-versus-olivere-golang-client/252248
- https://github.com/olivere/elastic/issues/1240
- https://github.com/olivere/elastic/issues/1240
- https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docker.html
- https://studygolang.com/articles/28869
62 changes: 62 additions & 0 deletions pkg/storage/elasticsearch/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package elasticsearch

import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"log"
"net"
"net/http"
"time"

es "github.com/elastic/go-elasticsearch/v7"
"github.com/elastic/go-elasticsearch/v7/esapi"
)

var (
ErrEsNotFound = errors.New("es: not found")
)

type EsClient struct {
client *es.Client
}

func NewESClient(hosts []string, username, password string) (client *EsClient, err error) {
c, err := es.NewClient(es.Config{
Addresses: hosts,
Username: username,
Password: password,
Transport: &http.Transport{
MaxIdleConnsPerHost: http.DefaultMaxIdleConnsPerHost,
ResponseHeaderTimeout: 5 * time.Second,
DialContext: (&net.Dialer{Timeout: 5 * time.Second}).DialContext,
TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS11,

Check failure

Code scanning / CodeQL

Insecure TLS configuration

Using insecure TLS version VersionTLS11 for MinVersion.
},
},
})
if err != nil {
log.Fatal(err)
}

return &EsClient{client: c}, nil
}

func (es *EsClient) handleResponse(resp *esapi.Response) (map[string]interface{}, error) {
var (
r map[string]interface{}
)
if resp.StatusCode == 404 {
return r, ErrEsNotFound
}
// Check response status
if resp.IsError() {
return nil, errors.New(resp.String())
}
// Deserialize the response into a map.
if err := json.NewDecoder(resp.Body).Decode(&r); err != nil {
return nil, errors.New(fmt.Sprintf("Error parsing the response body: %s", err))
}
return r, nil
}
191 changes: 191 additions & 0 deletions pkg/storage/elasticsearch/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package elasticsearch

import (
"context"
"log"
"testing"

"github.com/stretchr/testify/assert"
)

var (
esClient *EsClient
ctx context.Context
)

const (
indexName = "test-index"
)

func init() {
var err error
esClient, err = NewESClient([]string{"http://127.0.0.1:9200"}, "", "")
if err != nil {
log.Fatal(err)
}
ctx = context.Background()
}

func TestNewESClient(t *testing.T) {
t.Log(esClient.client.Info())
}

func TestNewESClientWithContext(t *testing.T) {
t.Log(esClient.client.Info(esClient.client.Info.WithContext(context.Background())))
}

func TestCreateIndex(t *testing.T) {
a := assert.New(t)
bodyStr := `{
"mappings" : {
"properties" : {
"id" : {
"index": true,
"type" : "keyword"
},
"age" : {
"index": true,
"type" : "keyword"
},
"nickname" : {
"index": true,
"type" : "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"bio" : {
"index": true,
"type" : "keyword"
}
}
}
}`
resp, err := esClient.CreateIndex(ctx, indexName, bodyStr)
a.Nil(err)
t.Log(resp)

response, err := esClient.client.Indices.Get([]string{indexName})
a.Nil(err)
t.Log(response)
}

func TestGetIndex(t *testing.T) {
a := assert.New(t)
response, err := esClient.GetIndex(ctx, indexName)
a.Nil(err)
t.Log(response)
}

func TestDeleteIndex(t *testing.T) {
a := assert.New(t)
err := esClient.DeleteIndex(ctx, indexName)
a.Nil(err)
}

func TestCreateDocument(t *testing.T) {
a := assert.New(t)
doc := map[string]interface{}{
"id": "1",
"nickname": "Tom",
"age": "18",
"bio": "I am a singer",
}
response, err := esClient.CreateDocument(ctx, indexName, "1", doc)
a.Nil(err)
t.Log(response)
}

func TestGetDocument(t *testing.T) {
a := assert.New(t)
response, err := esClient.GetDocument(ctx, indexName, "1")
a.Nil(err)
t.Log(response)
}

func TestUpdateDocument(t *testing.T) {
a := assert.New(t)
data := map[string]interface{}{
"bio": "I am a teacher",
}
response, err := esClient.UpdateDocument(ctx, indexName, "1", data)
a.Nil(err)
t.Log(response)
}

func TestUpdateDocumentByQuery(t *testing.T) {
a := assert.New(t)
query := map[string]interface{}{
"nickname": "Tom",
}
data := map[string]interface{}{
"bio": "I am a music teacher",
}
response, err := esClient.UpdateDocumentByQuery(ctx, indexName, query, data)
a.Nil(err)
t.Log(response)
}

func TestDeleteDocument(t *testing.T) {
a := assert.New(t)
err := esClient.DeleteDocument(ctx, indexName, "1")
a.Nil(err)
}

// 单个字段的搜索
func TestSearch(t *testing.T) {
a := assert.New(t)
query := map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
{
"match": map[string]interface{}{
"nickname": "Tom",
},
},
},
},
}
sort := map[string]interface{}{
"_score": map[string]interface{}{
"order": "desc",
},
}
response, total, err := esClient.Search(ctx, indexName, query, sort, 0, 10)
a.Nil(err)
t.Log(total)
t.Log(response)
}

// 多字段搜索
func TestSearchByMultiField(t *testing.T) {
a := assert.New(t)
query := map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
{
"match": map[string]interface{}{
"nickname": "Tom",
},
},
{
"match": map[string]interface{}{
"age": "18",
},
},
},
},
}
sort := map[string]interface{}{
"_score": map[string]interface{}{
"order": "desc",
},
}
response, total, err := esClient.Search(ctx, indexName, query, sort, 0, 10)
a.Nil(err)
t.Log(total)
t.Log(response)
}
Loading