MongoDB:WriteResult.getN()总是返回0?

viv*_*nam 11 mongodb mongodb-java

根据javaDoc,MongoDB-java中getN()WriteResult类方法返回opertion中更新的文档数.但即使正确插入文档,它也始终返回零.

为什么这样?或者我错误地理解了?

Nic*_*udo 10

我的印象是这是正常的MongoDB行为,与Java驱动程序无关.

我可以在文档中找到的唯一的事情就是这样:

如果前面的操作是更新或删除操作,则getLastError.n报告更新或删除的文档数.

insert一个既不update也不是remove,n似乎没有指定,并且0是一个很好的默认值作为任何.您可以在mongo shell中轻松检查它:

> db.test.insert({_id: 'test'})
> db.getLastErrorObj()
{ "n" : 0, "connectionId" : 7, "err" : null, "ok" : 1 }
Run Code Online (Sandbox Code Playgroud)

除非我弄错了,否则这不是一个问题:问问自己在什么情况下插入会失败(除了连接失败之外).我能想到的唯一一个是违反unicity约束,这会导致异常.因此,几乎按照定义,您接收WriteResult实例的事实意味着操作成功并插入了文档.

几个笔记:

  • 我以前的论点取决于你的WriteConcern足够高,以便报告错误.WriteConcern.NONE例如,如果您正在使用,则不会引发任何异常.
  • 如果更新文档的数量绝对是您必须的,您可以随时使用save而不是insert.不是很干净,但它表现得像你期望的那样.

  • 我认为这种行为存在问题,因为`getN()`的Javadoc说"*获取"n"字段,其中包含写入操作中受影响的文档数.*.如果执行[无序插入] ](http://docs.mongodb.org/manual/reference/method/db.collection.insert/#perform-an-unordered-insert),知道是否有任何改变,使用`getN()是很有价值的.然后总是返回0,在你的应用程序中引入一个错误.一个明智的解决方案(除了纠正Javadoc)可能是让`getN()`为插入抛出异常,或者首先不包括方法! (2认同)

wbd*_*rby 5

请注意,无论MongoDB 文档说明了什么,WriteResult.getN()方法总是为使用 Java 驱动程序插入的返回 0,无论插入的对象数量如何。Java驱动2.12.3中设置“n”字段的源码:

if (type == INSERT) {
  commandResult.put("n", 0);
} else if (type == REMOVE) {
  commandResult.put("n", bulkWriteResult.getRemovedCount());
} else if (type == UPDATE || type == REPLACE) {
  commandResult.put("n", bulkWriteResult.getMatchedCount() + bulkWriteResult.getUpserts().size());
  if (bulkWriteResult.getMatchedCount() > 0) {
    commandResult.put("updatedExisting", true);
  } else {
    commandResult.put("updatedExisting", false);
  }
  if (!bulkWriteResult.getUpserts().isEmpty()) {
    commandResult.put("upserted", bulkWriteResult.getUpserts().get(0).getId());
  }
}
Run Code Online (Sandbox Code Playgroud)

但是错误是通过异常正确报告的。例如,如果指定的 WriteConcern 至少是 ACKNOWLEDGED,则在插入违反唯一索引的文档时将抛出 MongoException