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

Mongo JAVA driver-3.6 iterator()反复迭代单个文档

储峻
2023-03-14

我试图使用Java Mongo驱动程序的FindIterable接口中定义的迭代器()来更新集合中的每个文档“Name”字段。迭代器上的next()函数应该给我下一个BSON对象,但实际上,它在迭代同一个对象。

public void func1(FindIterable<org.bson.Document> documents, MongoCollection<org.bson.Document> coll_name) {
    /*
     * This function will run until all the documents in a collection aren't retrieved.
     * */
    try {
        while (documents.iterator().hasNext()) {
           coll_name.updateOne(eq("_id", documents.iterator().next().get("_id")), new org.bson.Document("$set", new org.bson.Document("Name", getName((String) documents.iterator().next().get("NameSource")))));
            System.out.println("Document _id " + documents.iterator().next().get("_id") + " updated.....! in time : " + df.format(dater));
        }
    }catch (Exception ex){
        System.out.println(" ~~~~~~~~~~~Was not able to getName() & update document~~~~~~~~~~~~~~~~~~");
        System.out.println(ex.getMessage()) ;
    } finally {
        documents.iterator().close();
    }
}

调用函数:

  FindIterable<org.bson.Document> FRESH_docs = coll_name.find(exists("Text", false)).noCursorTimeout(true);

    int flag = 1;
    try{
        func1(FRESH_docs, coll_name, flag);
    }catch (Exception ex){
        System.out.println(" ~~~~~~~~~~~call to func1() failed for FRESH_docs ~~~~~~~~~~~~~~~~~~");
        System.out.println(ex.getMessage());
    }

输出是:

Document _id 4713205 updated.....! in time : 2017-12-25 08:56:42.876
Document _id 4713205 updated.....! in time : 2017-12-25 08:56:42.902
Document _id 4713205 updated.....! in time : 2017-12-25 08:56:42.930
Document _id 4713205 updated.....! in time : 2017-12-25 08:56:42.958
Document _id 4713205 updated.....! in time : 2017-12-25 08:56:42.984
Document _id 4713205 updated.....! in time : 2017-12-25 08:56:43.012
.....

我删除了日期时间打印机以进行干净的代码评估。有人能建议我在迭代同一个BSON文档时犯了什么错误吗?

共有1个答案

戚浩淼
2023-03-14

您处理光标的方式存在一些问题:

>

  • 调用 documents.iterator() 一次。查看源代码后,似乎在此调用中得到了一个新的迭代器。因此,每次想要前进到新版本时,您可能只是重新启动练习:

    MongoCursor<org.bson.Document> iterator = documents.iterator();
    while (iterator.hasNext()) {
       // process
    }
    

    您在一次迭代中多次调用iterator.next(),观察iterator.hasNext()。这是有问题的,当光标被取消时,您最终会调用Next()。建议的更改:

    //Call next once in the iteration and reuse the doc:
    while (iterator.hasNext()) {
       org.bson.Document nextDocument = iterator.next();
       coll_name.updateOne(eq("_id", nextDocument.get("_id")), new org.bson.Document("$set", new org.bson.Document("Name", getName((String) nextDocument.get("NameSource")))));
        System.out.println("Document _id " + nextDocument.get("_id") + " updated.....! in time : " + df.format(dater));
    }
    

    如你所见,第2点是在第1点的基础上建立起来的。

  •  类似资料:
    • 问题 你想反方向迭代一个序列 解决方案 使用内置的 reversed() 函数,比如: >>> a = [1, 2, 3, 4] >>> for x in reversed(a): ... print(x) ... 4 3 2 1 反向迭代仅仅当对象的大小可预先确定或者对象实现了 __reversed__() 的特殊方法时才能生效。 如果两者都不符合,那你必须先将对象转换为一个列表才行,比

    • 问题内容: 必须是O(n)并且是就地(空间复杂度为1)。下面的代码可以工作,但是有没有更简单或更完善的方法? 问题答案: 编辑以删除每次迭代的额外比较:

    • 我有一个来自req的数组。身体我需要循环并获取值,比如(quantity_1作为一个单独的数据,quantity_2作为单独的数据)如何从req获取这样的值和数组。正文是:

    • 我想标记中的所有控件。

    • 我有一个JSON文件,其中包含世界各地的大学列表。我想只获得特定的大学,其中数组中的字段与我需要选择的内容相匹配。我面临的问题是,每所大学都有自己的身份证号,这使得我无法弄清楚如何迭代数组。JSON文件可以在这个GitHub回购中找到。 使我将JSON文件转换为数组的代码: 我得到的一个样本是: 什么是最好的或适当的方式打印出来只有大学与或例如? 我读了Foreach循环上的留档和例子。但还是得不

    • 我目前正在面对mapstruct和它的初学者问题,其中一个是以下问题。 我知道示例方案:https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-iterable-to-non-iterable 希望对象结构清晰。在源代码中有两个列表,应该为每个列表选择第一个元素。MapStruct如何做到这一点?