本节主要介绍go语言对Elasticsearch文档的基础操作:创建、查询、更新、删除。
为了方便演示文档的CRUD操作,我们先定义索引的struct结构
// 定义一个文章索引结构,用来存储文章内容
type Article struct {
Title string // 文章标题
Content string // 文章内容
Author string // 作者
Created time.Time // 发布时间
}
添加文档
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/olivere/elastic/v7"
"log"
"os"
"time"
)
type Article struct {
Title string // 文章标题
Content string // 文章内容
Author string // 作者
Created time.Time // 发布时间
}
func main() {
// 创建client连接ES
client, err := elastic.NewClient(
// elasticsearch 服务地址,多个服务地址使用逗号分隔
elastic.SetURL("http://127.0.0.1:9200", "http://127.0.0.1:9201"),
// 基于http base auth验证机制的账号和密码
elastic.SetBasicAuth("user", "secret"),
// 启用gzip压缩
elastic.SetGzip(true),
// 设置监控检查时间间隔
elastic.SetHealthcheckInterval(10*time.Second),
// 设置请求失败最大重试次数
elastic.SetMaxRetries(5),
// 设置错误日志输出
elastic.SetErrorLog(log.New(os.Stderr, "ELASTIC ", log.LstdFlags)),
// 设置info日志输出
elastic.SetInfoLog(log.New(os.Stdout, "", log.LstdFlags)))
if err != nil {
// Handle error
fmt.Printf("连接失败: %v\n", err)
} else {
fmt.Println("连接成功")
}
// 执行ES请求需要提供一个上下文对象
ctx := context.Background()
// 定义一篇博客
blog := Article{Title:"golang es教程", Content:"go如何操作ES", Author:"tizi", Created:time.Now()}
// 使用client创建一个新的文档
put1, err := client.Index().
Index("blogs"). // 设置索引名称
Id("1"). // 设置文档id
BodyJson(blog). // 指定前面声明struct对象
Do(ctx) // 执行请求,需要传入一个上下文对象
if err != nil {
// Handle error
panic(err)
}
fmt.Printf("文档Id %s, 索引名 %s\n", put1.Id, put1.Index)
}
提示:后续的章节不再重复给出完整的代码,仅给出关键代码片段
查询文档
根据文档ID,查询文档
// 根据id查询文档
get1, err := client.Get().
Index("blogs"). // 指定索引名
Id("1"). // 设置文档id
Do(ctx) // 执行请求
if err != nil {
// Handle error
panic(err)
}
if get1.Found {
fmt.Printf("文档id=%s 版本号=%d 索引名=%s\n", get1.Id, get1.Version, get1.Index)
}
# 手动将文档内容转换成go struct对象
msg2 := Article{}
// 提取文档内容,原始类型是json数据
data, _ := get1.Source.MarshalJSON()
// 将json转成struct结果
json.Unmarshal(data, &msg2)
// 打印结果
fmt.Println(msg2.Title)
批量查询文档
通过多个Id批量查询文档,对应ES的multi get
// 查询id等于1,2,3的博客内容
result, err := client.MultiGet().
Add(elastic.NewMultiGetItem(). // 通过NewMultiGetItem配置查询条件
Index("blogs"). // 设置索引名
Id("1")). // 设置文档id
Add(elastic.NewMultiGetItem().Index("blogs").Id("2")).
Add(elastic.NewMultiGetItem().Index("blogs").Id("3")).
Do(ctx) // 执行请求
if err != nil {
panic(err)
}
// 遍历文档
for _, doc := range result.Docs {
// 转换成struct对象
var content Article
tmp, _ := doc.Source.MarshalJSON()
err := json.Unmarshal(tmp, &content)
if err != nil {
panic(err)
}
fmt.Println(content.Title)
}
更新文档
根据id更新文档
_, err := client.Update().
Index("blogs"). // 设置索引名
Id("1"). // 文档id
Doc(map[string]interface{}{"Title": "新的文章标题"}). // 更新Title="新的文章标题",支持传入键值结构
Do(ctx) // 执行ES查询
if err != nil {
// Handle error
panic(err)
}
根据条件更新文档
支持批量更新文档内容
_, err = client.UpdateByQuery("blogs").
// 设置查询条件,这里设置Author=tizi
Query(elastic.NewTermQuery("Author", "tizi")).
// 通过脚本更新内容,将Title字段改为1111111
Script(elastic.NewScript( "ctx._source['Title']='1111111'")).
// 如果文档版本冲突继续执行
ProceedOnVersionConflict().
Do(ctx)
提示: 复杂查询条件,请参考go es查询用法
删除文档
// 根据id删除一条数据
_, err := client.Delete().
Index("blogs").
Id("1"). // 文档id
Do(ctx)
if err != nil {
// Handle error
panic(err)
}
根据条件删除文档
_, _ = client.DeleteByQuery("blogs"). // 设置索引名
// 设置查询条件为: Author = tizi
Query(elastic.NewTermQuery("Author", "tizi")).
// 文档冲突也继续删除
ProceedOnVersionConflict().
Do(ctx)
提示: 复杂查询条件,请参考go es查询用法