万字详解!在 Go 语言中操作 ElasticSearch,建议收藏!
在大数据和搜索引擎技术不断进步的今天,ElasticSearch 已成为业界非常流行的搜索引擎解决方案,广泛应用于日志分析、全文搜索、数据分析等领域。对于 Go 语言开发者来说,olivere/elastic 是一个强大且易用的 ElasticSearch 客户端库,允许在 Go 应用中轻松操作 ElasticSearch。
本文将通过代码示例,详细介绍如何使用 olivere/elastic 包操作 ElasticSearch。
安装 olivere/elastic 包
首先,安装该客户端库。在终端中运行以下命令:
# 使用 v7 版本
go get github.com/olivere/elastic/v7
基础代码示例
确保已经有了运行中的 ElasticSearch 服务。以下是一个简单的 Go 应用示例,展示了如何使用 olivere/elastic 包连接 ElasticSearch 并执行基本操作。
package main
import (
"context"
"fmt"
"sync"
"github.com/olivere/elastic/v7"
)
var (
ESClient *elastic.Client
once sync.Once
)
const esUrl = "http://127.0.0.1:9200"
func main() {
// 创建 ES 连接
ConnectES(
elastic.SetSniff(false), // 禁用嗅探
elastic.SetURL(esUrl), // 设置服务地址
elastic.SetBasicAuth("", ""), // 设置认证账号和密码
)
// 测试连接,获取 ElasticSearch 版本
info, code, err := Ping(esUrl)
if err != nil {
panic(err)
}
fmt.Printf("Elasticsearch 版本: %s, 状态码: %d\n", info.Version.Number, code)
// 创建索引(如果不存在)
err = CreateIndexIfNotExists("my_index", `{"mappings":{"properties":{"name":{"type":"text"}}}}`)
if err != nil {
panic(err)
}
fmt.Println("ElasticSearch 操作成功!")
}
// ConnectES 创建 ES 客户端
func ConnectES(options ...elastic.ClientOptionFunc) {
once.Do(func() {
var err error
ESClient, err = elastic.NewClient(options...)
if err != nil {
panic(err)
}
})
}
// Ping 测试连接
func Ping(url string) (*elastic.PingResult, int, error) {
return ESClient.Ping(url).Do(context.Background())
}
// CreateIndexIfNotExists 创建索引(如果不存在)
func CreateIndexIfNotExists(index, mapping string) error {
ctx := context.Background()
exists, err := ESClient.IndexExists(index).Do(ctx)
if err != nil {
return err
}
if exists {
return nil
}
_, err = ESClient.CreateIndex(index).BodyString(mapping).Do(ctx)
return err
}
常见操作封装
创建连接
func ConnectES(options ...elastic.ClientOptionFunc) {
once.Do(func() {
var err error
ESClient, err = elastic.NewClient(options...)
if err != nil {
panic(err)
}
})
}
Ping 测试
func Ping(url string) (*elastic.PingResult, int, error) {
return ESClient.Ping(url).Do(context.Background())
}
创建索引(如果不存在)
func CreateIndexIfNotExists(index, mapping string) error {
ctx := context.Background()
exists, err := ESClient.IndexExists(index).Do(ctx)
if err != nil {
return err
}
if exists {
return nil
}
_, err = ESClient.CreateIndex(index).BodyString(mapping).Do(ctx)
return err
}
删除索引
func DeleteIndex(index string) (*elastic.IndicesDeleteResponse, error) {
return ESClient.DeleteIndex(index).Do(context.Background())
}
添加文档
func CreateDoc(index, id string, body interface{}) (*elastic.IndexResponse, error) {
return ESClient.Index().Index(index).Id(id).BodyJson(body).Do(context.Background())
}
更新文档
func UpdateDoc(index, id string, body interface{}) (*elastic.UpdateResponse, error) {
return ESClient.Update().Index(index).Id(id).Doc(body).Do(context.Background())
}
删除文档
func DeleteDoc(index, id string) (*elastic.DeleteResponse, error) {
return ESClient.Delete().Index(index).Id(id).Do(context.Background())
}
批量操作
批量添加
func CreateBulkDoc(index string, ids []string, body []interface{}) (*elastic.BulkResponse, error) {
bulkRequest := ESClient.Bulk()
for i, v := range body {
req := elastic.NewBulkIndexRequest().Index(index).Id(ids[i]).Doc(v)
bulkRequest = bulkRequest.Add(req)
}
return bulkRequest.Do(context.Background())
}
批量更新
func UpdateBulkDoc(index string, ids []string, body []interface{}) (*elastic.BulkResponse, error) {
bulkRequest := ESClient.Bulk()
for i, v := range body {
req := elastic.NewBulkUpdateRequest().Index(index).Id(ids[i]).Doc(v).DocAsUpsert(true)
bulkRequest = bulkRequest.Add(req)
}
return bulkRequest.Do(context.Background())
}
批量删除
func DeleteBulkDoc(index string, ids []string) (*elastic.BulkResponse, error) {
bulkRequest := ESClient.Bulk()
for _, id := range ids {
req := elastic.NewBulkDeleteRequest().Index(index).Id(id)
bulkRequest = bulkRequest.Add(req)
}
return bulkRequest.Do(context.Background())
}
查询操作
单个文档查询
func FirstDoc(index, id string) (*elastic.GetResult, error) {
return ESClient.Get().Index(index).Id(id).Do(context.Background())
}
条件查询
func QuerySearch(query elastic.Query) {
queryRet, err := ESClient.Search().Index("my_index").Query(query).Do(context.Background())
if err != nil {
panic(err)
}
fmt.Printf("查询结果总数: %d\n", queryRet.TotalHits())
for _, hit := range queryRet.Hits.Hits {
fmt.Printf("命中数据: %s\n", string(hit.Source))
}
}
总结
olivere/elastic 是 Go 语言中操作 ElasticSearch 的强大客户端库,提供了丰富的 API,支持多种操作。本篇通过代码示例,详细介绍了如何在 Go 应用中使用该库进行 ElasticSearch 的连接、创建索引、文档操作及查询等。
通过这些方法,你可以轻松将 ElasticSearch 集成到你的 Go 项目中,从而高效处理搜索和数据分析需求。