2012-03-29 13 views
1

既存のレコードの既存フィールドのMongodbで$ incを実行しています。 更新直後にgetLastErrorをチェックします。それは、ほとんどOK動作しますが、時にはそれが返されます:エラーがありませんでしたが、ゼロレコードが更新されます。Mongodbは既存のレコードを更新しません。

{nは、0、 connectionId、107、 errは、ヌル、[OK]を、1.0}

をこれは意味します(n = 0)。 返すと期待されるもの:1レコードが更新されました(n = 1)。 更新の直前に存在するrecord.fieldを確認します。レコードのための他の方法はありません。フィールドは消えます。

これはどのようにすることができますか?

公式のErlangドライバを使用していますが、ドライバの問題ではないようです。

コード:usersテーブルの

change_gold_amount(User, GoldDiff) when is_record(User, user) -> 
    {ok, {Document}} = find_one(users, {'_id', User#user.id}), 
    UserGold = bson:lookup(gold, Document, 0), 
    case UserGold + GoldDiff < 0 of 
     true -> 
      {error, not_enough_gold}; 
     false -> 
      {ok, LastErr} = do(fun() -> mongo:modify(users, 
                 {'_id', User#user.id}, 
                 {'$inc', {gold, GoldDiff}}), 
             mongo:command({getlasterror, 1}) 
           end), 
      case bson:lookup(n, LastErr) of 
       {1} -> {ok, User#user{gold=UserGold + GoldDiff}}; 
       _ -> {error, {mongo_error, LastErr}} 
      end 
    end. 

find_one(Collection, Selector) -> 
    do(fun() -> mongo:find_one(Collection, Selector) end). 

do(Fun) -> 
    mongo:do(safe, master, get_connection(), ?DB_NAME, Fun). 

レコードは "_id" と "金" フィールドを持っています。

ありがとうございました。

+0

文書構造、文書を挿入するために実行するドライバコード、文書を更新するために使用するドライバコードなど、より多くの情報を提供する必要があります。 – marr75

+0

ご返信ありがとうございます。私は更新機能コードサンプルとデータ構造に関するコメントを追加しました。挿入コードは、更新プログラムがDBからレコードを最初に取得するため、重要ではありません。 – Kpoxman

+0

私はあなたを助けたいと思っていますが、あなたのコードに間違いはありません。一方、私が働いている場所ではgetl​​asterrorは使用しません。私に教えてくれてありがとう。どのくらいの頻度でこのエラーが発生しますか? –

答えて

0

私はもう一度、ドライバコードを読んだことがあります。mongo:do関数はFun引数(接続、安全レベルなど)の実行中に同じ設定を提供しますが、ではなく mongo:doコール中に接続への排他的なアクセスを提供します。

これが当てはまる場合、関連のない操作に対してgetLastErrorが発生している可能性があります。

私が間違っている場合は、私に修正してください。

関連する問題