qmgo
qmgo copied to clipboard
关于在Update方法中设置upsert的问题
我希望能够实现如果文档不存在就插入的功能,在update的option中设置了upsert为true。
实际应用中,当匹配不到条件时,能够执行插入功能,但是会返回 mongo: no documents in result
错误信息。告诉我没有匹配结果。
按理说如果设置了upsert为true,那么就算没有匹配结果也应该是正常的,不应该返回这个错误吧。
这是业务代码
now := time.Now()
filter := bson.M{"year": now.Year(), "month": int(now.Month()), "day": now.Day(), "operate": operate}
update := bson.M{operator.Push: bson.M{"posts": item}}
var upset bool = true
option := options.UpdateOptions{
UpdateOptions: &mongoOptions.UpdateOptions{Upsert: &upset},
}
err := db.Mongo.Collection(this.table()).UpdateOne(context.TODO(), filter, update, option)
if err != nil {
fmt.Println(err)
}
在源码的 collection.go
的217行,对匹配条件进行判断,如果匹配结果数量为0,就会返回未匹配错误,并没有对upsert进行判断。
res, err := c.collection.UpdateOne(ctx, filter, update, updateOpts)
if res != nil && res.MatchedCount == 0 {
err = ErrNoSuchDocuments
}
if err != nil {
return err
}
当文档未匹配时,res的MatchedCount为0,UpsertedCount为1。
是否应该对upsert的结果进行判断,来决定要不要返回 ErrNoSuchDocuments
错误呢?
例如进行如下修改,如果没有设置upsert,或者设置了upsert但值为false的话,才返回未匹配错误。
res, err := c.collection.UpdateOne(ctx, filter, update, updateOpts)
if res != nil && res.MatchedCount == 0 {
if updateOpts.Upsert == nil || *updateOpts.Upsert == false {
err = ErrNoSuchDocuments
}
// 其他判断条件 如 if UpsertedCount == 0 { err = upsert错误 }
}
if err != nil {
return err
}
返回这个错误就是告知调用者到底是update还是insert吧
我也遇到了这个问题,看官方怎么解决吧