2012-03-29 4 views
1

기존 레코드의 기존 필드에 대해 $ inc를 Mongodb에서 수행하고 있습니다. 업데이트 직후에 getLastError를 확인합니다. 그것은 주로 확인을 작동하지만, 경우에 따라서는 반환Mongodb가 기존 record.field를 업데이트하지 않습니다.

{N, 0, connectionId, 107, ERR, 좋아, 널 (null), 1.0}

이 의미 :이 오류는 없었으나 제로 레코드가 업데이트됩니다 (n = 0). 반환 할 것으로 기대되는 것 : 1 개의 레코드가 업데이트되었습니다 (n = 1). 업데이트 직전에 존재하는 record.field를 확인합니다. 그리고 기록을위한 다른 방법은 없습니다. 필드가 사라집니다.

어떻게 될 수 있습니까?

공식 Erlang 드라이버를 사용하지만 드라이버 문제가 아닌 것 같습니다.

코드 : 사용자 테이블의

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

도와 드리고 싶지만 코드에 문제가없는 것은 아닙니다. 반면에 우리는 내가 일하는 곳에서 getlasterror를 사용하지 않습니다. 가르쳐 줘서 고마워. 얼마나 자주이 오류가 발생합니까? –

답변

0

나는 드라이버 코드를 다시 한 번 읽고, Fun 인수 (연결, 안전 수준 등)를 실행하는 동안 mongo : do 함수가 동일한 설정을 제공하지만, 이 아닌을 제공한다는 것을 알았습니다. mongo : do 호출하는 동안 연결에 대한 독점적 인 액세스를 제공합니다.

이것이 사실이라면 관련없는 작업에 대해 getLastError가 표시 될 수 있습니다.

내가 잘못하면 저를 교정하십시오.

관련 문제