截至 MongoDB 版本 4,是否有一种方法可以使用另一个字段的值来更新 MongoDB 字段?
在MongoDB v4中,是否有一种方法可以使用另一个字段的值更新一个MongoDB字段?
问题的出现原因:
- MongoDB不是事务安全的,这意味着在find()和save()之间,另一个用户可能会修改文档。
解决方法:
- 使用迭代方法通过文档进行更新,具体的解决方法如下:
db.person.find().snapshot().forEach( function (elem) { db.person.update( { _id: elem._id }, { $set: { name: elem.firstname + ' ' + elem.lastname } } ); } );
其他相关讨论:
- 使用save()方法完全替换文档,应该使用update()方法。
- 可以尝试使用db.person.update()方法进行更新。
- 如果无法访问db.eval(),可以使用上述方法。
- 可以通过添加查询过滤器来使更新更"原子化",例如查询过滤器为{ _id: elem._id, firstname: elem.firstname, lastname: elem.lastname}。
- 可以使用save()方法进行更新,但是需要确保在forEach运行期间没有其他更新操作发生。另外,snapshot方法在v3.6版本后已被弃用。
以上就是关于在MongoDB v4中使用另一个字段的值更新MongoDB字段的问题的出现原因以及解决方法的整理。
根据上述内容,可以整理出以下文章:
自MongoDB 3.4版本以来,有一种高效的方法可以更新一个mongodb字段为另一个字段的值。这个方法可以参考styvane在Stack Overflow上的回答。
过时的答案如下:
在更新操作中,你不能引用文档本身(尚未支持)。你需要遍历文档并使用一个函数来更新每个文档。可以参考这个答案,或者使用服务器端的eval()函数。
这个答案在今天仍然有效吗?
看起来是的。我没有在MongoDB文档中找到任何提到在更新操作中引用当前文档的内容。相关的功能请求也仍然未解决。
在2017年4月,这个答案仍然有效吗?或者已经有新的功能可以实现这个目的吗?
看起来仍然有效。而且-van-der-rest在2013年指出的功能请求仍然处于OPEN状态。
这个答案现在已经无效了,请看回答。
截至MongoDB v 4,是否有一种方法可以使用另一个字段的值更新MongoDB字段?
问题的出现原因:
在MongoDB v4之前的版本中,更新一个字段的值为另一个字段的值比较困难。过去,没有直接的方法可以在更新操作中使用聚合管道来实现这一点。这导致了一些开发者在处理这个问题时遇到了困难。
解决方法:
从MongoDB v4.2开始,可以使用聚合管道在更新操作中更新字段的值。具体的解决方法如下:
1. 使用聚合管道的方式更新字段的值:
db.collection.updateOne( {}, [ {"$set": {"name": { "$concat": ["$firstName", " ", "$lastName"]}}} ] )
这种方法使用了`$set`操作符来设置字段的值为另一个字段的值。需要注意的是,第二个参数中使用了方括号来指定聚合管道而不是普通的更新文档。
2. 使用聚合管道操作符更新字段的值:
db.collection.aggregate( [ { "$addFields": { "name": { "$concat": [ "$firstName", " ", "$lastName" ] } }}, { "$out":
这种方法使用了`$addFields`操作符来添加一个新的字段,并将其值设置为另一个字段的值。需要注意的是,这种方法不会直接更新集合,而是将结果保存到一个新的集合中。
3. 使用`$project`操作符和`$set`更新操作符更新字段的值:
var cursor = db.collection.aggregate([ { "$project": { "name": { "$concat": [ "$firstName", " ", "$lastName" ] } }} ]) var requests = []; cursor.forEach(document => { requests.push( { 'updateOne': { 'filter': { '_id': document._id }, 'update': { '$set': { 'name': document.name } } } }); if (requests.length === 500) { db.collection.bulkWrite(requests); requests = []; } }); if(requests.length > 0) { db.collection.bulkWrite(requests); }
这种方法使用了`$project`操作符和`$set`更新操作符来更新字段的值。需要注意的是,这种方法需要使用`bulkWrite`方法来执行更新操作。
从MongoDB v4.2开始,可以使用聚合管道来更新MongoDB字段的值。使用`$set`操作符或`$addFields`操作符可以实现这一操作。在之前的版本中,也有一些解决方法,但不如使用聚合管道方便和高效。