Elasticsearch

名称类型适用场景
go-elasticsearch官方客户端新项目和需要跟进 Elasticsearch 新版本的项目
olivere/elastic链式 API 客户端仍使用 Elasticsearch 7 的存量项目

olivere/elastic 已废弃,不支持 Elasticsearch 8 及以上版本。新项目应使用官方 go-elasticsearch,并选择与 Elasticsearch 主版本对应的 Go 模块版本。

下面的示例都使用同一个文档,并省略客户端初始化、响应解析和错误处理:

type User struct {
    Name string `json:"name"`
}

user := User{Name: "Alice"}

go-elasticsearch

官方客户端与 Elasticsearch REST API 基本一一对应,请求体需要编码为 JSON。

body, _ := json.Marshal(user)

es.Index("users", bytes.NewReader(body),
    es.Index.WithDocumentID("1")) // 增
es.Get("users", "1")             // 查

es.Update("users", "1", strings.NewReader(`{
    "doc": {"name": "Bob"}
}`))                               // 改
es.Delete("users", "1")          // 删

搜索时直接传入 Query DSL:

query := `{
    "query": {
        "match": {"name": "Alice"}
    }
}`

es.Search(
    es.Search.WithIndex("users"),
    es.Search.WithBody(strings.NewReader(query)),
)

大量写入时可使用官方 esutil.BulkIndexer,避免手动拼接 Bulk API 请求。

olivere/elastic

通过链式 API 构建请求,可以直接传入结构体和查询对象。

client.Index().Index("users").Id("1").BodyJson(user).Do(ctx) // 增
client.Get().Index("users").Id("1").Do(ctx)                  // 查

client.Update().Index("users").Id("1").
    Doc(map[string]any{"name": "Bob"}).Do(ctx)               // 改
client.Delete().Index("users").Id("1").Do(ctx)               // 删

查询构建器可以组合 Query DSL,无需手写 JSON:

query := elastic.NewMatchQuery("name", "Alice")

result, _ := client.Search().
    Index("users").
    Query(query).
    Do(ctx)