Mongo 5.0 如何用findOneAndUpdate聚合管道实现带默认值计数器
问题根因
你的代码执行异常是两个写法错误导致的:
- 没有将更新逻辑包装为数组格式:MongoDB只有在更新参数传入数组时,才会将内容识别为聚合更新管道、解析其中的聚合表达式;如果传普通对象,会把你写的
$cond结构当做普通字段值直接写入文档,这就是你看到$cond数组被存到value字段的直接原因。 - 聚合管道内不能直接使用普通更新操作符
$inc:管道阶段需要用聚合算术运算符实现数值运算,自增逻辑要替换为$add表达式。
另外你传入的更新选项里多写了一行name: options.name,这是无效配置,没有作用可以直接删掉。
可直接运行的正确实现
这个方案在MongoDB 4.2及以上版本都可正常运行,你使用的5.0.9版本完全兼容,仅需单次数据库调用即可实现带默认初始值的计数器自增upsert,不需要多次数据库交互:
const result = await context.params.tenantDb.collection('counters').findOneAndUpdate( { // 查询过滤条件 name: options.name, }, [ // 注意这里必须用数组包裹,标识这是聚合更新管道 { $set: { value: { $cond: { if: { $eq: [{ $type: "$value" }, "missing"] }, then: 1000, // 新插入文档时的计数器初始值,可按需修改 else: { $add: ["$value", 1] } // 文档已存在时计数器自增1 } } } } ], { returnDocument: 'after', upsert: true, } );
补充说明
如果需要调整自增步长,直接修改$add里的第二个参数即可;如果需要调整初始值,修改then对应的数值就行。
内容的提问来源于stack exchange,提问作者Joe Jankowiak
相关产品推荐
相关产品推荐

