首页 > golang > gin集成ElasticSearch操作库
2021
02-12

gin集成ElasticSearch操作库

介绍

Elasticsearch(ES)是一个基于Lucene构建的开源、分布式、RESTful接口的全文搜索引擎。Elasticsearch还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,ES能够横向扩展至数以百计的服务器存储以及处理PB级的数据。可以在极短的时间内存储、搜索和分析大量的数据。通常作为具有复杂搜索场景情况下的核心发动机。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎。

1.集成流程

2.安装

这里使用olivere/elastic,@注意: 下载包的版本需要和ES版本相同,如我们这里使用的ES是7.13.3的版本,那么我们就需要下载olivere/elastic/v7

# 安装v7的版本
go get github.com/olivere/elastic/v7

3.编辑主配置文件

文件位置:./config.ini

[elastic]
# 是否开启
enable=true
# 服务地址,多个地址用逗号隔开
url=http://10.10.0.3:9200
# 是否转换请求地址,默认为true,当等于true时 请求http://ip:port/_nodes/http,将其返回的url作为请求路径
sniff=false
# 心跳检测间隔 单位s
healthcheckInterval=5
# 日志前缀
logPre=ES-

4.定义全局变量

编辑文件:./common/elastic.go

package common

import (
   "github.com/olivere/elastic/v7"
   "github.com/spf13/viper"
   "time"
)

var GvaElastic *elastic.Client // ES客户端
// 创建es客户端
func InitES() {
   // 配置
   enable := viper.GetBool("elastic.enable")
   if enable {
      // 创建客户端
      client, err := elastic.NewClient(
         elastic.SetURL(viper.GetString("elastic.url")),
         elastic.SetSniff(viper.GetBool("elastic.sniff")),
         elastic.SetHealthcheckInterval(time.Duration(viper.GetInt("elastic.healthcheckInterval"))*time.Second),
         elastic.SetBasicAuth("username", "passwd"), // 账号密码
         //elastic.SetErrorLog(global.GvaLogger),
         //elastic.SetInfoLog(global.GvaLogger),
      )
      if err != nil {
         panic("创建ES客户端错误:" + err.Error())
      }
      GvaElastic = client
   }
}

5. 集成入口

编辑文件:./main.go

func main() {
    ...
  common.InitES()
  ...
}

6. 创建测试,测试完成

新建文件:./controller/test/test.go

func EsAction(ctx *gin.Context) {
   es := common.GvaElastic
   id := "1"
   res, err := es.Get().Index("report_alias").Id(id).Do(ctx)
   if err != nil {
      fmt.Println("查询失败", err)
      ctx.JSON(200, gin.H{
         "message": err.Error(),
      })
      return
   }
   ctx.JSON(200, gin.H{
      "message": err,
      "res":     res,
      "source":  res.Source,
   })
}


示例

#创建索引
func main(){
    client.CreateIndex(indexname).Do(context.Background())
}

#删除索引
func main(){
    client.DeleteIndex(indexname).Do(context.Background())
}

#结构体形式创建文档

type user struct {
	name string
	age int
}

func main(){
    u := user{
		name: "wunder",
		age: 18,
	}
	_, err := client.Index().
    	Index("index_name").  		// 索引名称
    	Id("id").					// 指定文档id
    	BodyJson(u).				// 可序列化JSON
    	Do(context.Background())
	
    if err != nil {
		panic(err)
	}
}

#字符串形式

u := `{"name":"wunder", "age": 1}`
_, err := client.Index().
	Index("index_name").  		// 索引名称
	Id("id").					// 指定文档id
	BodyJson(u).				// 可序列化JSON
	Do(context.Background())

if err != nil {
	panic(err)
}

#修改文档

#elasticsearch的修改文档是可以直接用创建去替换,如果单字段修改可以使用以下修改:

_, err := client.Update().
	Index("index_name").
	Id("id").
	Doc(map[string]interface{}{"name":"wunder"}). // 需要修改的字段值
	Do(context.Background())

if err != nil {
	panic(err)
}

#批量操作

type user struct {
	id string
	name string
	age int
}
func main() {
	users := []user{
		{
			id: "1",
			name: "wunder",
			age: 18,
		},
		{
			id: "2",
			name: "sun",
			age: 20,
		},
	}
	bulkRequest := client.Bulk()   								//初始化新的BulkService。
	for _, u := range users {
		doc := elastic.NewBulkUpdateRequest().Id(u.id).Doc(u)  	// 创建一个更新请求
		bulkRequest = bulkRequest.Add(doc)						// 添加到批量操作
	}
	_, err := bulkRequest.Do(context.Background())
	if err != nil {
		panic(err)
	}

}

#删除文档  注意:在实际开发中不建议直接删除文档,可以定义delete_time字段做逻辑删除。


_, err := client.Delete().Index("index_name").
		Id("id").
		Do(context.Background())
if err != nil {
   panic(err)
}


#查询文档

ret, err := client.Get().Index("index_name").
		Id("id").					// 文档id 
		Do(context.Background())
if err != nil {
	panic(err)
}
fmt.Printf("id:%s \n Source:%s ", ret.Id, string(ret.Source))


var query elastic.Query

// match_all
query = elastic.NewMatchAllQuery()

// term
query = elastic.NewTermQuery("field_name", "field_value")

// terms
query = elastic.NewTermsQuery("field_name", "field_value")

// match
query = elastic.NewMatchQuery("field_name", "field_value")

// match_phrase
query = elastic.NewMatchPhraseQuery("field_name", "field_value")

// match_phrase_prefix
query = elastic.NewMatchPhrasePrefixQuery("field_name", "field_value")

//range Gt:大于; Lt:小于; Gte:大于等于; Lte:小于等
query = elastic.NewRangeQuery("field_name").Gte(1).Lte(2)

//regexp
query = elastic.NewRegexpQuery("field_name", "regexp_value")

_, err := client.Search().Index("index_name").Query(query).Do(context.Background())

if err != nil {
	panic(err)
}


#组合查询

// 创建新的bool查询
query := elastic.NewBoolQuery()

// must
query.Must(elastic.NewTermQuery("name", "wunder"))

// should
query.Should(elastic.NewTermQuery("age", 18))

//must_not
query.MustNot(elastic.NewTermQuery("age", 20))

// 结果: {"bool":{"must":{"term":{"name":"wunder"}},"must_not":{"term":{"age":20}},"should":{"term":{"age":18}}}}

_, err := client.Search().Index("index_name").Query(query).Do(context.Background())
if err != nil {
	panic(err)
}

#其他筛选

// 文档查询数量,默认为10。
client.Search().Index("index_name").Size(100).Do(context.Background())

//开始搜索的索引,默认为0。
client.Search().Index("index_name").From(100).Do(context.Background())

//排序顺序, true为降徐, false为升序
client.Search().Index("index_name").Sort("field_name", true).Do(context.Background())

// 还可以通过SortBy进行多个排序
sorts := []elastic.Sorter{
	elastic.NewFieldSort("field_name01").Asc(), // 升序
	elastic.NewFieldSort("field_name02").Desc(), // 降徐
}
client.Search().Index("index_name").SortBy(sorts...).Do(context.Background())

// 返回指定字段
includes:= []string{"name", "age"}
include := elastic.NewFetchSourceContext(true).Include(includes...)
client.Search().Index("index_name").FetchSourceContext(include).Do(context.Background())

//查询的总命中计数
client.Search().Index("index_name").TrackTotalHits(true).Do(context.Background())

#打印bool查询语句

// 创建新的bool查询
query := elastic.NewBoolQuery()

query.Must(elastic.NewTermQuery("name", "wunder"))

source, _ := query.Source()
fmt.Println(source)
// 结果:map[bool:map[must:map[term:map[name:wunder]]]]



本文》有 0 条评论

留下一个回复

dictpoetrycybazhishic-juzic-lishic-fanwen范本下载