2013-05-09 7 views
9

メソッド[1]を使用して文書をアップカウント(インクリメントまたは挿入)しようとすると、このエラー[2]が時折発生します。Mongodb upsert throw DuplicateKeyException

[1]

public NGram save(final NGram ngram) { 
    Criteria cr = where("_id").is(ngram.getNgram()) 
      .and("f3c").is(ngram.getF3c()) 
      .and("tokCount").is(ngram.getTokCount()) 
      .and("first").is(ngram.getFirst()) 
      ; 
    if(ngram.getTokCount() > 1) { 
     cr.and("second").is(ngram.getSecond()); 
    } 
    if(ngram.getTokCount() > 2) { 
     cr.and("third").is(ngram.getThird()); 
    } 
    final Query qry = new Query(cr); 
    final Update updt = new Update().inc("count", ngram.getCount()); 
    template.upsert(qry, updt, NGram.class); 
    return ngram; 
} 

[2]

Caused by: org.springframework.dao.DuplicateKeyException: E11000 duplicate key error index: sytrue.ngram.$_id_ dup key: { : "page two" }; nested exception is com.mongodb.MongoException$DuplicateKey: E11000 duplicate key error index: sytrue.ngram.$_id_ dup key: { : "page two" } 
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:52) 
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:1665) 
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:390) 
at org.springframework.data.mongodb.core.MongoTemplate.doUpdate(MongoTemplate.java:920) 
at org.springframework.data.mongodb.core.MongoTemplate.upsert(MongoTemplate.java:894) 
at com.sytrue.ngram.repo.impl.NGramRepositoryImpl.save(NGramRepositoryImpl.java:43) 
at sun.reflect.GeneratedMethodAccessor41.invoke(Unknown Source) 

アップサートは、私にこの例外を返すことは決してありません。私は正しい?私はちょうど、次のことかもしれないが推測してい

+0

2つのアップセルトが同時に起こっていますか? –

+0

いいえ、私はキューを介してこれらのupsertsをシリアル化しています。 – biliboc

答えて

16

問題:

は、あなたは多くの基準に基づいて検索操作を行っています。つまり、(条件で)パラメータの不一致が原因で失敗した場合は、ドキュメントを挿入しようとします。

同じ文書を同じ_idで更新しようとしていますが、他の条件の一部が一致していないため、重複したキーの例外が発生する可能性があります。以下の例を考えてみてください。

test:Mongo > db.example.update({ _id : 1, a : 1, b : 1},{ $set : {d : 1}}, true, false) 
test:Mongo > db.example.find() 
{ "_id" : 1, "a" : 1, "b" : 1, "d" : 1 } 
test:Mongo > db.example.update({ _id : 1, a : 1, b : 2},{ $set : {d : 1}}, true, false) 
E11000 duplicate key error index: test.example.$_id_ dup key: { : 1.0 }