2

我正在编写一个相当大的迁移并且有这个代码(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

现在效果很好,但看起来真的很奇怪。请问这一切背后的意义何在?

4

1 回答 1

3

当您修改一个对象时,它可能会被数据库移动。数据库需要额外注意记住哪些对象已经被访问过。此功能称为快照,您可以使用快照查询

db.collection.find().snapshot()

但是,即使这样也不能保证在游标迭代期间插入或删除的对象。文档链接中解释了更多注意事项。

另一种选择是$orderby在不变的唯一索引上执行。理想情况下,该索引也是单调的,因此如果您使用 ObjectIds 作为主键,那么该_id字段非常方便,例如

db.collection.find().sort({"_id" :1});
于 2013-04-19T13:23:59.593 回答