我正在写一个非常大的迁移并且有这个代码(coffeescript):
db.users.find().forEach (user)->
try
#some code changing the user depending on the old state
db.users.save(user)
print "user_ok: #{user._id}"
catch error
print "user_error: #{user._id}, error was: #{error}"
发生了一些错误。但它们发生在已经处理过的用户身上:
user_ok: user_1234
#many logs
user_error: user_1234 ...
循环如何处理已处理的对象?
我最终做了:
backup = { users: [] }
db.users.find().forEach (user)->
try
#some code changing the user depending on the old state
backup.users.push user
print "user_ok: #{user._id}"
catch error
print "user_error: #{user._id}, error was #{error}"
#loop backup and save
它现在很好用,但看起来很奇怪。这一切背后有什么意义呢?
答案 0 :(得分:3)
修改对象时,数据库可能会移动它。数据库需要额外注意以记住已经访问过哪些对象。此功能称为snapshotting,您可以使用
请求快照查询db.collection.find().snapshot()
但是,即使这样也不能保证在游标迭代期间插入或删除的对象。在文档的链接中解释了一些警告。
另一种选择是对不可变的唯一索引执行$orderby
。理想情况下,该索引也是单调的,因此如果您使用ObjectIds作为主键,那么_id
字段非常方便,例如
db.collection.find().sort({"_id" :1});