介绍
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 条评论