当前位置: 首页 > 知识库问答 >
问题:

使用Mongo光标时更新文档的正确方法是什么?

娄学文
2023-03-14

我正在尝试使用光标更新Mongo DB中的一个文档。我的Mongo DB Java驱动程序版本是3.3.0。下面是我的代码片段。

MongoCollection<Document> collection = mongoDb.getCollection("customer");
MongoCursor<Document> cursor = collection.find().iterator();
try{
    while(cursor.hasNext()){
        Document oldDoc = cursor.next();
        //created new Document newDoc
        collection.replaceOne(oldDoc, newDoc);
    }
}catch(Exception e){
    e.printStackTrace();
}

虽然这样,我可以更新文档,我认为这不是有效的方法,因为这里的集合被搜索了2次。我想用一些值更新旧文档,然后想用一些方法保存它,比如Collection.update(oldDoc)或Collection.save(oldDoc)而不创建新文档。我搜索了一下,偶然发现了下面的帖子。

Java,MongoDB:如何在迭代庞大集合的同时更新每个对象

  1. 在Mongo DB Java driver 3.3.0 API中,我可以在迭代游标的同时更新或保存文档的save()方法是什么?
  2. 在Mongo DB Java driver 3.3.0 API中,有没有可以更新现有文档而不创建新文档的方法?
  3. 上面的链接显示save()以前是Mongo DB Java驱动程序API的一部分。有专家的回答吗,为什么它从API中删除了?

共有1个答案

何安宜
2023-03-14

不用担心额外的搜索,replaceOne方法的第一个参数是筛选器。使用旧的doc作为筛选器将使用文档的_id属性,这应该比较快。所以基本上,你做这件事的方式是正确的。但请记住,该操作是非事务性的,这意味着更新可能会影响游标的结果集。因此,可能会发生这样的情况,即更新的文档将存储在光标尚未通过的位置,导致文档被处理两次。

关于你的问题。

>

  • mongo shell中save方法的语义是更新或插入尚未存在的文档(又名upsert)。与MongoCollection最接近的是UpdateOne(),其中UpdateOptionsUpsert设置为true。这基本上就是save命令所做的。但是replaceOne会导致相同的结果,如果替换文档是原始文档的修改版本。

    UpdateOptions upsert = new UpdateOptions().upsert(true);
    Bson idFilter = Filters.eq("_id", oldDoc.getObjectId("_id"));
    //modify the oldDoc
    oldDoc. ...
    collection.replaceOne(idFilter, oldDoc, upsert);
    

  •  类似资料:
    • 我在我的网络应用程序中使用spring mongo。当我在Tomcat7中取消部署应用程序时,内存泄漏。我怀疑可能是我没有明确关闭的Mongo对象。我想知道关闭它的正确方式(和位置)。

    • 问题内容: 即使在使用Java Swing一年以上之后,对我来说,它仍然像魔术一样。如何正确使用BufferStrategy,尤其是方法? 我想添加一个JFrame和一个Canvas,然后进行绘制。我还希望能够调整()画布的大小。每次我调整Canvas的大小时,似乎都会被浪费掉,或者变得毫无用处,因为在上使用并没有真正做任何事情。另外,它具有怪异的不确定性行为,我不知道如何正确同步它。 这就是我的

    • 问题内容: 我想在Linux上使用该机制。我希望我的应用程序知道何时更改了文件。能否请您提供给我一个示例,该怎么做? 问题答案: 文档(来自具有inotify的Monitor文件系统活动) 在C API 提供了三个系统调用来构建各种文件系统监视器: 在内核中创建子系统的实例,并在成功和失败时返回文件描述符。与其他系统调用一样,如果失败,请检查诊断。 顾名思义,它增加了一块 手表 。每个监视都必须提

    • 问题内容: 需要帮助,以了解如何在UIKit中使用prepareForReuse()。该文件说 您只应重置与内容无关的单元格属性,例如Alpha,编辑和选择状态 但是如何重置单个属性属性(例如isHidden)呢? 假设我的单元格有2个标签,我应该在哪里重置: 标签文本 label.numberOfLines label.isHidden 我的tableView(_:cellForRowAt :)

    • 一段时间以来,我一直试图将我的tableview工作作为一种电子表格,通过背景线程进行更新,当单元格更新时,它会亮起几秒钟(更改样式),然后返回到原始样式。我已经知道,我不能直接在表格单元格中存储和设置样式,我需要某种支持类来保存这些数据。但是tableview“重用”单元格(使用相同的单元格处理不同的数据)的行为真的很奇怪。当所有单元格都适合屏幕时,它对我来说完美无瑕,但一旦我放置大约100个单

    • 我想更新现有mongodb文档中的字段。但设定值应为旧值和新值的平均值。 我可以从mongodb文档中获取旧值并计算平均值,并将其设置到字段中,但这不是线程安全性,在计算平均值时,mongodb文件中的旧值可能会更改。 示例,文档: { ' _ id ':ObjectId(" 55d 49338 b 9796 c 337 c 894 df 3 "),值:10 } Python代码: 以前: { '