MongoDB Go驱动如何无条件移除数组全部元素 $pull与$set性能对比
解决方案
为什么你当前的$pull代码不生效
$pull操作符的逻辑是移除数组中所有匹配指定条件的元素,你传入nil作为匹配条件,只会移除数组中值为nil的元素,不会清空整个数组,所以不符合你的预期。
如何用$pull实现数组清空
可以传入一个能匹配数组内所有元素的通用条件即可实现清空,示例代码如下:
r := col.FindOneAndUpdate(ctx, bson.M{ `UserId`: UserId, }, bson.M{ `$pull`: bson.M{ `Array`: bson.M{`$exists`: true}, }, }, options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.Before))
这里$exists: true会匹配数组中的所有元素,因此所有元素都会被移除。
两种方案的性能对比
$set直接赋值为空数组的性能远优于$pull清空:
$pull需要遍历数组的每一个元素,逐一判断是否符合匹配条件后再执行移除,时间复杂度为O(n)(n为数组长度),数组越长开销越大$set是直接修改字段的值,不需要遍历数组内容,无论原数组有多少元素,时间复杂度都是O(1)
额外注意事项
如果开启了upsert配置,两种方案的行为有差异:
- 当匹配不到文档执行插入时,
$set会在新文档中生成值为空数组的Array字段 - 当匹配不到文档执行插入时,
$pull不会在新文档中生成Array字段
你可以根据自己的业务需求选择合适的方案,正常情况下优先选择$set方案即可。
内容的提问来源于stack exchange,提问作者aj3423
相关产品推荐
相关产品推荐

