Go语言操作Elasticsearch全流程示例:连接、增删改查
本文详细演示了如何使用Go语言的 go-elasticsearch 库连接并操作Elasticsearch集群。内容包含完整的初始化连接、文档索引写入、基于布尔逻辑的查询与结果解析、使用Painless脚本进行单条/批量更新,以及单条与批量删除数据的代码示例。
前提准备与客户端连接
在使用Go操作Elasticsearch前,需安装官方推荐的SDK库。在Go项目中引入依赖:
import (
es8 "github.com/elastic/go-elasticsearch/v8"
)配置连接信息时,建议将敏感信息(如密码)从代码中剥离。以下示例展示如何构建Client并验证连通性:
conf := es8.Config{
Addresses: []string{"http://127.0.0.1:9200"}, // 注意:Address应为切片类型
Username: "elastic",
Password: "你的实际密码", // 请替换为真实的ES密码
}
client, err := es8.NewClient(conf)
if err != nil {
log.Fatalf("创建es客户端失败: %v", err)
}
// 验证连接
res, err := client.Info(es8.Info.WithContext(context.Background()))
if err != nil {
log.Fatalf("连接es失败: %v", err)
}
log.Println("成功连接Elasticsearch")注意:原文中的 Addresses: "http..." 写法存在类型错误,es8.Config 的 Addresses 字段要求是 []string 类型,且必须添加 context 以符合最新SDK规范。
创建索引与写入数据
Elasticsearch无需预先定义映射(Mapping),首次写入数据时会自动创建索引并动态生成字段类型。这里定义一个结构体用于模拟待写入的数据。
定义模型结构
type Admin struct {
ID int `json:"id"`
UserName string `json:"user_name"`
RealName string `json:"real_name"`
Mobile string `json:"mobile"`
}写入单条文档
将结构体序列化为JSON后,通过 Index 方法写入。设置 WithDocumentID 可以指定文档唯一ID,避免自动生成导致的不确定性;WithRefresh("true") 可立即生效搜索结果(生产环境建议设为false以提升性能)。
admin := Admin{
ID: 1,
UserName: "test",
RealName: "测试用户",
Mobile: "15222222222",
}
body, err := json.Marshal(admin)
if err != nil {
log.Fatal(err)
}
res, err := client.Index(
"my_index", // 索引名称
bytes.NewReader(body), // 数据体
client.Index.WithDocumentID("1"), // 文档ID
client.Index.WithRefresh("true"), // 刷新策略
)
if err != nil {
log.Fatal(err)
}搜索数据
构建查询DSL并使用 Search 方法发起请求。对于嵌套较深的返回结果,定义对应的Go结构体有助于类型安全地解析数据。
定义响应结构
type EsResponse struct {
Hits struct {
Total struct {
Value int `json:"value"`
} `json:"total"`
Hits []struct {
Id string `json:"_id"`
Source map[string]any `json:"_source"`
} `json:"hits"`
} `json:"hits"`
}
// 简化后的业务返回结构
type ResultData struct {
TotalCount int `json:"total_count"`
Items []map[string]any `json:"items"`
}执行搜索
示例使用 bool -> must 组合查询多个字段的精确匹配。注意:若字段类型为 keyword 则使用 match_phrase 或 term,若为 text 则根据分词情况选择。match_phrase 对顺序有严格要求。
query := map[string]any{
"query": map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{"match_phrase": map[string]any{"user_name": "test"}},
{"match_phrase": map[string]any{"mobile": "15222222222"}},
},
},
},
}
qBody, _ := json.Marshal(query)
res, err := client.Search(
client.Search.WithIndex("my_index"),
client.Search.WithBody(bytes.NewReader(qBody)),
client.Search.WithPretty(),
)
if err != nil {
log.Fatal(err)
}
// 解析结果
var response EsResponse
if err := json.NewDecoder(res.Body).Decode(&response); err != nil { ... }
var result ResultData
result.TotalCount = response.Hits.Total.Value
for _, hit := range response.Hits.Hits {
hit.Item["_id"] = hit.Id // 补充ID到源数据
result.Items = append(result.Items, hit.Source)
}修改数据
Elasticsearch支持使用Painless脚本动态修改字段,适合部分字段更新场景。相比全量替换,这种方式更高效。
单条修改
使用 Update 接口配合 Script 语法修改指定ID的文档。
updateScript := map[string]any{
"script": map[string]any{
"source": "ctx._source.user_name=params.un; ctx._source.mobile.params.mo",
"params": map[string]any{
"un": "updated_test",
"mo": "15211111111",
},
"lang": "painless",
},
}
uBody, _ := json.Marshal(updateScript)
_, err := client.Update(
"my_index", // 索引
"1", // 文档ID
bytes.NewReader(uBody),
client.Update.WithRefresh("true"),
)
if err != nil {
log.Fatal(err)
}批量修改 (UpdateByQuery)
若需根据条件批量更新数据,使用 UpdateByQuery 接口。
bulkUpdate := map[string]any{
"query": map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{"match_phrase": map[string]any{"user_name": "test"}},
},
},
},
"script": map[string]any{
"source": "ctx._source.mobile='new_mobile';",
"lang": "painless",
},
}
bBody, _ := json.Marshal(bulkUpdate)
_, err := client.UpdateByQuery(
[]string{"my_index"},
client.UpdateByQuery.WithBody(bytes.NewReader(bBody)),
client.UpdateByQuery.WithRefresh(true),
)
if err != nil {
log.Fatal(err)
}删除数据
删除操作分为针对已知ID的单条删除,以及基于查询条件的批量删除。
单条删除
res, err := client.Delete(
"my_index",
"1",
client.Delete.WithRefresh("true"),
)
if err != nil {
log.Fatal(err)
}批量删除
构造查询语句来匹配待删除的记录,效率极高,但需注意确认查询条件以免误删。
delQuery := map[string]any{
"query": map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{"match_phrase": map[string]any{"mobile": "15222222222"}},
},
},
},
}
dBody, _ := json.Marshal(delQuery)
_, err := client.DeleteByQuery(
[]string{"my_index"},
bytes.NewReader(dBody),
client.DeleteByQuery.WithRefresh(true),
)
if err != nil {
log.Fatal(err)
}以上就是Go语言操作Elasticsearch全流程(连接、写入、查询、修改、删除)的详细内容,更多关于Go语言集成Elasticsearch实战的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









