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


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

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


11440
2018-02-15 11:49


起源

它工作正常。您使用的是哪种mongo版本?此操作后文档是否正确插入数据库? - Buchi
是的文件被正确插入! Mongo版本:2.2.2 - vivek_jonam
我也发现了同样的事情。它返回0.见这里 stackoverflow.com/questions/10662858/... - btiernay
您可以添加失败的测试和示例数据来显示问题吗? - Trisha
@Trisha这不是一个错误的行为。 getN()仅在更新时返回文档计数,对于插入,它始终返回0。 - vivek_jonam


答案:


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

我在文档中唯一能找到的是 这个

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

一个 insert 既不是 update 也不是 removen 似乎没有指定,0和任何默认值一样好。您可以在mongo shell中轻松检查它:

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

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

几个笔记:

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

10
2017-09-06 14:19



我认为这种行为存在问题,因为Javadoc for getN() 说:“获取“n”字段,其中包含写入操作中受影响的文档数。。如果你做了 无序插入,知道是否有任何改变和使用是很有价值的 getN() 然后通过始终返回0在您的应用程序中引入一个错误。一个明智的解决方案(除了纠正Javadoc)可能是 getN() 为插入抛出异常,或者首先不包括该方法! - Zero3
@ Zero3无序插入比这个答案更新。另外,WriteResult包含自2.6以来插入文档的数量,我相信你只需要用正确的名称调用getField。最后,最新的javadoc没有说明n字段是什么,它只是说'得到n字段'。虽然这不是非常有用,但它几乎不正确。如果你看看n字段的官方mongodb文档,很明显插入将产生n值为0 - 可能不是最佳行为,但根据规范是正确的行为。只需使用正确的字段。 - Nicolas Rinaudo
写结果 在最新版本和描述中没有这样的功能 getN() 就像我写的那样。检查自己:)。 - Zero3
当然。 写结果: 成功后,WriteResult对象包含有关插入的文档数的信息。你是对的 getN 我错误地认为最新的javadoc版本是2.6。 - Nicolas Rinaudo
是的,所以对于无序插入,你想要使用 BulkWriteOperation,通过 initializeUnorderedBulkOperation,最终产生一个 BulkWriteResult,有一个 getInsertedCount 方法。 - Nicolas Rinaudo


注意,不管是什么 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());
  }
}

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


4
2018-01-15 18:38





您可能还想检查 http://docs.mongodb.org/manual/core/write-concern/

dafault行为不是使用“安全”写入问题


1
2017-09-06 13:15