栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

Go Elasticsearch 删除快速入门

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Go Elasticsearch 删除快速入门


文章目录
  • 1.根据 ID 删除
  • 2.根据条件删除
  • 3.批量删除
  • 4.FAQ
    • 4.1 elastic: Error 409 (Conflict)
  • 参考文献

本文借助第三方库 olivere/elastic 完成 Go 对 ES 的删除操作。

Go 对 Elasticsearch 的增删改查参见完整博文 Go Elasticsearch 增删改查(CRUD)快速入门。

1.根据 ID 删除

可以根据文档 ID 删除对应的文档。

// Delete 通过 ID 删除文档
func Delete(ctx context.Context, index, id string) error {
	_, err := GetESClient().Delete().Index(index).Id(id).Refresh("true").Do(ctx)
	return err
}

注意:重复删除会报elastic: Error 404 (Not Found)错。

对应 RESTful API 为:

DELETE /es_index_userinfo/_doc/1?refresh=true
2.根据条件删除

我们也可以根据条件来删除符合条件的文档,即 Delete by Query。即使没有符合条件的文档,也不会报 404 错误。

// DeleteByQuery4ES 根据条件删除文档。
// param: index 索引; query 条件。
// return: 删除的文档数; error。
func DeleteByQuery4ES(ctx context.Context, index string, query elastic.Query) (int64, error) {
	rsp, err := GetESClient().
		DeleteByQuery(index).
		Query(query).
		Refresh("true").
		Do(ctx)
	if err != nil {
		return 0, err
	}
	return rsp.Deleted, nil
}

注意:Refresh 只能指定 true 或 false(缺省值),不能指定 wait_for。

比如我们删除昵称为 cat 且年龄小于等于18 的用户。

query := elastic.NewBoolQuery()
query.Filter(elastic.NewTermQuery("nickname", "cat"))
query.Filter(elastic.NewRangeQuery("age").Lte(18))
ret, err := DeleteByQuery4ES(context.Background(), index, query)

对应的 RESTful API 为:

POST /es_index_userinfo/_delete_by_query?refresh=true
{
  "query":{
     "bool":{
       "filter":[
			{"term" : {"nickname" : "cat"}},
			{"range" : {"age" : {"lte" : 18}}}
		]
     }
  }
}
3.批量删除

借助 BulkService + BulkDeleteRequest 可实现对文档的批量删除。

注意: 指定的文档不存在不会报错,会返回实际删除的文档数。

// DeleteBulk 删除文档批量(部分失败会返回失败)
// rets 删除的数量, error
func DeleteBulk(ctx context.Context, index string, ids []string) (int, error) {
	bulkService := GetESClient().Bulk().Index(index).Refresh("true")
	for i := range ids {
		req := elastic.NewBulkDeleteRequest().Id(ids[i])
		bulkService.Add(req)
	}
	res, err := bulkService.Do(ctx)
	return len(res.Succeeded()), err
}

示例:

func main() {
	ctx := context.Background()
	// 全部成功
	// 1 和 2 均存在
	ids := []string{"1", "2"}
	num, err := DeleteBulk(ctx, "es_index_userinfo", ids)
	fmt.Printf("DeleteBulk all success, num=%v err=%vn", num, err)

	// 部分成功
	// 3 存在 33 不存在
	ids = []string{"3", "33"}
	num, err = DeleteBulk(ctx, "es_index_userinfo", ids)
	fmt.Printf("DeleteBulk partial success, num=%v, err=%vn", num, err)

	// 全部失败
	// 44 和 55 均不存在
	ids = []string{"44", "55"}
	num, err = DeleteBulk(ctx, "es_index_userinfo", ids)
	fmt.Printf("DeleteBulk all failed, num=%v err=%vn", num, err)
}

输出:

DeleteBulk all success, num=2 err=
DeleteBulk partial success, num=1, err=
DeleteBulk all failed, num=0 err=

对应的 Restful API:

POST es_index_userinfo/_bulk
{"delete":{"_id" : "1"}}
{"delete":{"_id" : "2"}}
{"delete":{"_id" : "3"}}
{"delete":{"_id" : "33"}}
{"delete":{"_id" : "44"}}
{"delete":{"_id" : "55"}}
4.FAQ 4.1 elastic: Error 409 (Conflict)

Elasticsearch 会在删除文档前使用查询时获取的 internal 版本号和当前文档版本号进行对比。如果在查询和删除操作之间文档发生更改,则会导致版本冲突并且删除操作失败,报 elastic: Error 409 (Conflict) 错误。

解决版本冲突一般有三个方法:

  • 重试。

重试不保证一定会删除成功,一般情况下在重试时冲突的概率会小很多。

  • 跳过冲突的文档并继续执行删除。

我们可以选择在发生冲突时是继续执行剩余的文档删除操作(proceed),还是终止返回(abort),缺省是 abort。

如删除索引 my-index-000001 中所有文档,跳过发生冲突的文档。

POST my-index-000001/_delete_by_query?conflicts=proceed
{
  "query": {
    "match_all": {}
  }
}
  • 根据ID批量删除(强制删除)。

我们可以分两步走,一步是查询符合条件的文档,一步是根据文档 ID 进行批量删除。这相当于忽略查询与删除操作间的变更,进行强制删除。

查询操作参见 Go Elasticsearch 查询快速入门。


参考文献

elastic - pkg.go.dev
elastic - type DeleteService
elastic - type DeleteByQueryService
elastic - type BulkService
elastic - BulkDeleteRequest
Elasticsearch Guide [8.1] » REST APIs » Document APIs » Delete by query API

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/909103.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号