用 Go Typed Client 快速上手 Elasticsearch —— 从建索引到聚合的完整实战

1. 准备工作

bash 复制代码
go get github.com/elastic/go-elasticsearch/v9

小贴士

  • 如果你的集群启用了安全特性,需要在 elasticsearch.Config 中配置 Username/Password 或 APIKey。
  • Typed Client 通过 NewTypedClient 创建,内部复用 *http.Client,建议全局单例化,避免频繁建立连接。
go 复制代码
cfg := elasticsearch.Config{
	Addresses: []string{"https://es.local:9200"},
	Username:  "elastic",
	Password:  "mypassword",
	// APIKey: "...", 二选一
}
es, _ := elasticsearch.NewTypedClient(cfg)

2. 创建索引并映射字段

go 复制代码
import (
	"context"
	"github.com/elastic/go-elasticsearch/v9/typedapi/indices/create"
	"github.com/elastic/go-elasticsearch/v9/typedapi/types"
)

_, err := es.Indices.Create("test-index").
	Request(&create.Request{
		Mappings: &types.TypeMapping{
			Properties: map[string]types.Property{
				"price": types.NewIntegerNumberProperty(), // 自动设置 "type":"integer"
			},
		},
	}).
	Do(context.Background())
if err != nil { /* 处理异常 */ }

要点

关键点 说明
types.NewIntegerNumberProperty() Builder 会自动注入 type=integer,避免手写字符串
.Request() 接收强类型结构体,写错字段编译期即报错
.Do(ctx) 统一执行入口,返回 *Response 与 error

3. 写入文档

3.1 直接传递结构体(最常用)

go 复制代码
doc := struct {
	Id    int    `json:"id"`
	Name  string `json:"name"`
	Price int    `json:"price"`
}{1, "Foo", 10}

if _, err := es.Index("test-index").
	Request(doc).
	Do(context.Background()); err != nil {
	log.Fatal(err)
}

3.2 传递已序列化的 JSON

go 复制代码
payload := []byte(`{"id":1,"name":"Foo","price":10}`)
_, err := es.Index("test-index").Raw(payload).Do(context.Background())

适用于手动拼装 或性能敏感 场景,跳过 encoding/json 二次编码。

4. 读取文档

go 复制代码
resp, err := es.Get("test-index", "1").Do(context.Background())
if err != nil { ... }
fmt.Printf("Source=%s\n", resp.Source_)

5. 判断文档是否存在

go 复制代码
ok, err := es.Exists("test-index", "1").IsSuccess(context.Background())
switch {
case err != nil:
	// 请求失败
case ok:
	fmt.Println("文档存在")
default:
	fmt.Println("文档不存在")
}

IsSuccess 通过 HTTP 状态码 判断,内部已处理 404 与重定向。

6. 搜索

6.1 使用强类型 Request 构建 DSL

go 复制代码
import "github.com/elastic/go-elasticsearch/v9/typedapi/search"

resp, err := es.Search().
	Index("test-index").
	Request(&search.Request{
		Query: &types.Query{
			Match: map[string]types.MatchQuery{
				"name": {Query: "Foo"},
			},
		},
	}).
	Do(context.Background())

生成的 DSL

json 复制代码
{
  "query": { "match": { "name": { "query": "Foo" } } }
}

6.2 快速解析命中

go 复制代码
for _, hit := range resp.Hits.Hits {
	var d struct {
		Name  string `json:"name"`
		Price int    `json:"price"`
	}
	if err := json.Unmarshal(hit.Source_, &d); err != nil { ... }
	fmt.Printf("%s => %d\n", d.Name, d.Price)
}

7. 聚合 ------ 求价格总和

go 复制代码
total, err := es.Search().
	Index("test-index").
	Request(&search.Request{
		Size: some.Int(0), // 只要聚合结果,不要文档
		Aggregations: map[string]types.Aggregations{
			"total_prices": {
				Sum: &types.SumAggregation{Field: some.String("price")},
			},
		},
	}).
	Do(context.Background())
if err != nil { ... }

sum := total.Aggregations.Sum("total_prices").Value
fmt.Printf("价格总和:%.0f\n", *sum)
  • some.Int(0) 与 some.String() 是 Typed API 的 可空包装器 ,避免 *int 指针声明的繁琐。
  • 结果通过 Aggregations.Sum("name") 类型安全地取出,无需手写 map 断言。

8. 进阶实践 & 性能建议

  1. 单例客户端 :在 main() 或 DI 容器里初始化一次,复用连接池。
  2. Context 超时 :在高并发场景用 context.WithTimeout 控制慢查询。
  3. Bulk 批量索引 :大规模写入请使用 es.Bulk() + 并行 worker。
  4. 显式 Refresh :测试场景可在写入后 .Refresh("wait_for"),生产环境由索引刷新策略决定。
  5. Typed vs. Raw:Typed API 更安全、可读;Raw/Low-level Client 更灵活。可按模块混用。

9. 小结

  • Typed Request + Builder 让映射、DSL、聚合都拥有 IDE 自动补全和编译期校验。
  • 常见场景(建索引 / CRUD / Search / Aggs)几乎只需一两行链式调用即可搞定。
  • 掌握 some 包 的可空包装器、IsSuccess 以及 Do(ctx) 的范式,能写出既易读又健壮的 Go-ES 代码。

一步到位搭建起 Go × Elasticsearch 的类型安全数据层,让你的业务逻辑远离魔法字符串,尽享编译器的守护!

相关推荐
microrain3 小时前
SagooIoT 的数据接入层只有四张表,却能接住三种外部数据
物联网·golang·数据建模·sagooiot
fly-iot4 小时前
【FDE知识库】(4):企业知识库怎么选型,开源知识库分享几个,选择开源协议友好的版本,开发wiki-go项目
golang·开源·开源协议
修心光5 小时前
记录一次,jenkins打包异常问题
运维·jenkins
Elasticsearch6 小时前
使用 Qoder 将 CSV 文件导入 Elasticsearch
elasticsearch
福大大架构师每日一题6 小时前
excelize v2.11.1发布:Go 1.26.0起步,16项安全修复与嵌入对象能力全面升级
开发语言·安全·golang
后台模板学习7 小时前
GitHub Actions 与 Jenkins 在日志监
运维·github·jenkins
Elastic 中国社区官方博客7 小时前
AgentHack Shanghai|基于阿里云AI搜索 Elasticsearch x Qoder 构建AI Agent应用
大数据·人工智能·elasticsearch·搜索引擎·阿里云·云计算·全文检索
小小龙学IT7 小时前
Go 语言 pprof 性能剖析与调优深度解析:把“卡在哪“变成一张可执行的数据图
开发语言·后端·golang
无言听风雨丶8 小时前
Kubernetes GitOps 持续交付实战:用 Argo CD 让 Git 成为集群事实源
git·elasticsearch·kubernetes
十二同学啊8 小时前
Go 工程化详解:项目结构、代码规范、测试体系与 CI/CD 实践
ci/cd·golang·代码规范