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()

ただし、これでも、カーソルの反復中に挿入または削除されたオブジェクトについては保証されません。ドキュメントへのリンクには、さらにいくつかの注意事項が説明されています。

もう 1 つのオプションは$orderby、不変の一意のインデックスに対して実行することです。理想的には、そのインデックスも単調であるため、ObjectIds を主キーとして使用している場合、_idフィールドは次のように非常に便利です。

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