MongoDB Java驱动程序3.4+光标到数组

时间:2017-10-10 08:40:34

标签: java mongodb mongodb-query mongodb-java

问题非常简单明了。我不想使用游标,因为它会大大增加我的操作时间,我想立即获取所有文档并通过方法执行来缓存它们。

        MongoClient mongoClient = new MongoClient( "HOST" );
        MongoDatabase db = mongoClient.getDatabase( "DB" );
        MongoCollection<Document> collection = db.getCollection( "COLLECTION" );
        FindIterable<Document> iterable = externalobjects.find( new Document( "test", "123" ) );

所以,我想将上面的iterable转换成一个列表,如何使用find并将游标转换为数组?

1 个答案:

答案 0 :(得分:1)

FindIterable不包含您找到的文件&#39;相反,它充当服务器端游标的句柄,并且为了从该服务器端游标中提取数据并将它们存储在应用程序的列表中,您必须读取文档和添加到您的列表中。例如:

// Java 8
List<Document> asList = new ArrayList<>();
documents.forEach((Consumer<Document>) d -> asList.add(d));

// Guava
List<Document> asList = Lists.newArrayList(documents);

// old skool
List<Document> asList = new ArrayList<>();
for (Document d : documents) {
    asList.add(d);
}

没有任何魔力,也没有捷径。

FWIW,这听起来有点不寻常:

  

我不想使用光标,因为它会大大缩短我的操作时间

通常减少操作时间是一件好事;)我猜你可能意味着它会以某种方式降低性能?如果是这样,FindIterable将使用FindOperationIterable作为迭代器的MongoBatchCursorAdapter换行。根据{{​​3}} t批处理游标的行为是:

  

MongoDB以批处理方式返回查询结果,此接口提供了这些批处理的迭代器。第一次调用下一个方法将返回第一个批次,后续调用将触发请求以获取下一批结果。客户端可以通过在下一次调用之间设置batchSize属性来控制批量大小。

因此,FindIterable用于减少find()调用结果的堆内覆盖(在应用程序内),并允许应用程序根据需要获取结果。这里有一个很大的警告:默认批量大小为(IIRC)100,因此如果您正在读取大量的100个文档,那么迭代FindIterable将导致多次回调到MongoDB服务器(每个一个)结果集中的100个docuemnts)。也许这是你遇到的问题?如果是这样,那么您可以将批处理大小设置为一个数字,该数字可以实现MongoDB服务器端调用数与应用程序中可用堆之间的折衷。您可以像这样设置批处理大小:

int batchSize = ...;
FindIterable<Document> iterable = externalobjects
    .find(new Document("test", "123"))
    .batchSize(batchSize);