通过迭代MongoDB集合来计算它的数量';我不能给出正确的计数

通过迭代MongoDB集合来计算它的数量';我不能给出正确的计数,mongodb,mongodb-query,mongodb-java,Mongodb,Mongodb Query,Mongodb Java,使用以下代码,我将迭代MongoDB集合以计算其计数。(使用循环、限制和排序方式_id递增) 忽略这样一个事实:有其他方法来计算计数,因为我使用这种方法来做其他事情(这段代码只是说明了我无法取出所有文档的事实) 但它并没有给出正确的计数。 我收集的文件总数应该是12637833, 但使用以下代码,打印的计数为12602135 也就是说,它们之间大约有3万个缺口 有人能帮助解决这个问题吗?谢谢 DBObject query = new BasicDBObject(); DBObject s

使用以下代码,我将迭代MongoDB集合以计算其计数。(使用循环、限制和排序方式_id递增)

忽略这样一个事实:有其他方法来计算计数,因为我使用这种方法来做其他事情(这段代码只是说明了我无法取出所有文档的事实)

但它并没有给出正确的计数。 我收集的文件总数应该是12637833, 但使用以下代码,打印的计数为12602135

也就是说,它们之间大约有3万个缺口

有人能帮助解决这个问题吗?谢谢

DBObject query = new BasicDBObject();
    DBObject sorter = new BasicDBObject("_id", 1);
    ObjectId largestObjectId = null;
    int count = 0;
    while (true) {  
        DBCursor cursor = c.find(query).sort(sorter).limit(200000);
        if (!cursor.hasNext()) {
            break;
        }
        while (cursor.hasNext()) {
            count++;
            BasicDBObject document = (BasicDBObject) cursor.next();
            if (document == null) {
                continue;
            }
            largestObjectId = (ObjectId) document.get("_id");
        }

        query = new BasicDBObject("_id", new BasicDBObject("$gt", largestObjectId));


        cursor.close();
    }

   System.out.println("Total Count is: " + count) 

只有在一个线程读取数据而另一个线程将某些内容写入数据库的环境中(即,在一个多线程应用程序中,一个线程写入mongodb,另一个线程执行某些操作),文档计数不匹配才会发生

此外,当我们使用DBCursor对12637833条记录的集合进行迭代时,并不是所有的记录最初都会加载到内存(JVM内存),而是从数据库中延迟获取


有趣的是,在多线程应用程序中,您可以发现DBCursor length和迭代游标并获取计数之间的差异,因为在DBCursor上使用length或toArray时,会不可避免地将DBCursor变成数组。因此,在调用DBCursor中的toArray或length之前,应该采取额外的预防措施,因为它会突然增加内存中的记录。假设我们有一千万条记录,那么内存中将有一千万个元素数组。因此,在DBCursor中使用length或toArray之前,请始终使用skip()和limit()来最小化结果。

只有在一个线程读取数据而另一个线程将某些内容写入数据库的环境中,才会出现文档计数不匹配的情况(即,在多线程应用程序中,一个线程写入mongodb,另一个线程执行某些操作)

此外,当我们使用DBCursor对12637833条记录的集合进行迭代时,并不是所有的记录最初都会加载到内存(JVM内存),而是从数据库中延迟获取


有趣的是,在多线程应用程序中,您可以发现DBCursor length和迭代游标并获取计数之间的差异,因为当我们在DBCursor上使用length或toArray时,会不可避免地将DBCursor变成数组。因此,在调用DBCursor中的toArray或length之前,应该采取额外的预防措施,因为它会突然变为数组减少内存中的记录。假设我们有一千万条记录,那么内存中将有一千万个元素数组。因此,始终使用skip()和limit()在DBCursor中使用length或toArray之前最小化结果。

这是一个分片集合吗?感谢@hyades的回复。是的。可能与有关。您可以尝试聚合查询而不是
查找
查询
[{$match:query},{$sort:{sorter},{$limit 200000}]
谢谢@hyades。让我试试,谢谢!@hyades。聚合只支持16M RAM,这不适用于我的情况。在我的情况下,每个文档都在32K以上,即限制应仅在500以下(不包括一些真正大的文档)有办法绕过这个大小限制吗?谢谢!这是一个分片集合吗?谢谢@hyades的回复。是的。也许它与有关。您可以尝试聚合查询而不是
查找
查询
[{$match:query},{$sort:{sorter},{$limit:200000}]
谢谢@hyades。让我试试,谢谢!@hyades。聚合只支持16M RAM,这不适用于我的情况。在我的情况下,每个文档都在32K以上,即限制应仅在500以下(不包括一些非常大的文档)。有没有办法绕过此大小限制?谢谢!