当我尝试使用方法[1]插入(增加或插入)文档时,我不时会收到此错误[2].
[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)
Upsert永远不会给我这个例外.我对吗?
我猜的问题可能是:
您正在根据许多标准进行查找操作.这意味着如果由于param(在标准中)的任何不匹配而失败,那么它将尝试插入文档.
因此,很有可能,您尝试使用相同的_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 }