product-consumer项目写入ES问题

来源:7-15 索引商品数据(一)

404_

2024-04-02

有两个问题。
第一个问题:在product-consumer项目 MsgHandler函数中有这么一个逻辑:如果是更新操作,且IsShow!=0时,消费消息 以create方式在ES中新建文档。

case global.OperationUpdate:
		if productMsg.IsShow == 0 { // 未上架
			err := esClient.DeleteRefresh(context.Background(), global.IndexName,
				strconv.FormatInt(productIndex.Id, 10),
				strconv.Itoa(productIndex.CateId))
			if err != nil {
				global.LOG.Error("DeleteRefresh error", err, "id", productIndex.Id)
			}
		} else { // 就是这一段代码
			esClient.BulkCreate(global.IndexName, strconv.FormatInt(productIndex.Id, 10),
				strconv.Itoa(productIndex.CateId), productIndex)
		}

但是有没有这样一种场景:先进行创建操作global.OperationCreate 且 IsShow!=0时,消费消息 以create方式在ES中新建文档。然后,我要修改商品信息,比如修改了价格,但是IsShow还是 !=0,那就会走上面case中的else语句中的create操作,但是ES中已经有了_id=productIndex.Id的文档了,创建一定不会成功的。所以这个逻辑是不是有问题?
如下是我改的代码:

case "update":
		if productMsg.IsShow == 0 {
			// 是更新操作,但是一定修改了isShow字段,不在前端展示了。ES中删除这条数据
			err := esClient.Delete(context.Background(), "shop-product", strconv.FormatInt(productIndex.Id, 10), "")
			if err != nil {
				logx.Errorf(fmt.Sprintf("删除数据失败,error: %s", err.Error()))
			}
		} else {
			// 是更新操作,但是前端还有展示,ES中需要更新这条数据。
			// 先查询。如果能查到,就走更新逻辑
			get, _ := esClient.Get(context.Background(), "shop-product", strconv.FormatInt(productIndex.Id, 10), "")
			if get == nil {
				// 如果没有查询到则执行新增操作
				esClient.BulkCreate("shop-product", strconv.FormatInt(productIndex.Id, 10), "", productIndex)
			} else {
				esClient.EsClient.Update().Index("shop-product").Id(strconv.FormatInt(productIndex.Id, 10)).Doc(productIndex).Do(context.Background())
			}
	}

问题二:如何对错误进行断言呢?
比如 用我们封装的ES操作的函数esClient.Get()这个方法,会返回err,我们如何判断这个err是 record not found 这error呢?还是 es集群不可用这种error呢?

写回答

1回答

少林码僧

2024-04-02

  1. 不要先get再update,这种更新方式很低效,会增加集群负载,可以直接调用BulkReplacef方法用最新的数据进行覆盖;

  2. 找不到不会抛出error,可以使用返回的result中的Found字段判断,为false表示没找到文档

https://img1.sycdn.imooc.com/szimg/660bdb7009b5464113770538.jpg

1
0

海量数据高并发场景,构建Go+ES8企业级搜索微服务

全新 ES8 配合技术组件,实现高性能搜索

267 学习 · 54 问题

查看课程