MongoDB:新增数组元素时如何将version设为数组长度减一
MongoDB集合文档的两个更新功能实现
原始文档结构
{ "_id": { "$oid": "63e8af476a3674484ea14888" }, "my_id": 321123, "version": 0, "parameters": [ {"a": 1}, {"a": 1, "b": 2} ] }
需求说明
需要实现两个RESTful API对应的MongoDB更新操作:
- 功能1:将
version字段修改为0到len(parameters)之间的任意数值 - 功能2:向
parameters数组新增一个对象,同时将version设置为新增后数组长度减1(示例效果如下)
{ "_id": { "$oid": "63e8af476a3674484ea14888" }, "my_id": 321123, "version": 2, "parameters": [ {"a": 1}, {"a": 1, "b": 2}, {"a": 1, "b": 2, "c": 3} ] }
尝试的错误写法
db.parameters.findOneAndUpdate({"my_id": 321123}, {"$inc":{version: parameters}, "$push":{"a": 1, "b": 2, "c": 3}}, upsert=true) db.parameters.findOneAndUpdate({"my_id": 321123}, {"$inc":{version: {"$size": parameters}}, "$push":{"a": 1, "b": 2, "c": 3}}, upsert=true)
解决方案
功能1:修改version字段(带合法性校验)
利用$expr在查询条件中验证新version的范围,确保修改值在合法区间内:
// 示例:将version修改为1 db.parameters.findOneAndUpdate( { "my_id": 321123, // 验证新version值在0到当前parameters数组长度之间 "$expr": { "$and": [ {"$gte": [1, 0]}, {"$lte": [1, {"$size": "$parameters"}]} ] } }, {"$set": {"version": 1}}, {returnNewDocument: true} )
说明:$expr允许在查询条件中引用当前文档的字段值,通过$size获取parameters的长度,确认新version符合要求后,用$set直接赋值。
功能2:新增参数并同步更新version
使用聚合管道类型的更新,实现字段间的关联计算:
// 示例:向parameters新增对象{a:1, b:2, c:3},并设置version为新数组长度-1 db.parameters.findOneAndUpdate( {"my_id": 321123}, [ // 先向数组添加新元素 {"$push": {"parameters": {"a": 1, "b": 2, "c": 3}}}, // 计算新数组长度减1,赋值给version {"$set": {"version": {"$subtract": [{"$size": "$parameters"}, 1]}}} ], {upsert: true, returnNewDocument: true} )
错误原因说明
- 使用
$inc属于逻辑错误:$inc仅用于数值的固定增减,无法引用字段或使用表达式计算值 - 普通更新操作(非聚合管道)不支持引用当前文档的其他字段值,必须通过聚合管道实现字段关联计算
内容的提问来源于stack exchange,提问作者Netanel
相关产品推荐
相关产品推荐

