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
不要先get再update,这种更新方式很低效,会增加集群负载,可以直接调用BulkReplacef方法用最新的数据进行覆盖;
找不到不会抛出error,可以使用返回的result中的Found字段判断,为false表示没找到文档
10
相似问题
代码链接ES报超时问题
回答 1
ES同步写入和异步写入的两个问题
回答 1