有没有一种方法可以将FindIterable<Document>转换为JSONArray字符串?

5
我得到了类似这样的东西。
MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase(db);
MongoCollection<Document> collection = database.getCollection(col);

FindIterable<Document> results = collection.find();

我可以使用以下方法获取JSONArray字符串:

JSON.serialize(results)

但在最新版本的mongodb驱动程序中,它已被弃用。

而在MongoDB shell中,我可以使用:

db.$.find().toArray();

但是我在Java驱动程序中没有找到类似的内容。

我使用一个列表并迭代游标来解决这个问题。

MongoCursor<Document> cursor = results.iterator();
List<String> list = new ArrayList<String>(); 

while(cursor.hasNext())
    list.add(cursor.next().toJson());

return list.toString();

无论如何,欢迎提出更好的解决方案。


1
你正在做的事情(对每个“Document”进行迭代并调用toJson())是使用JSON实用程序类的推荐替代方法。从弃用该类的提交中可以看到:“应用程序应将其使用替换为JsonReader、JsonWriter以及包装它们的BasicDBObject上的toJson/parse方法。”。 - glytching
2个回答

7
使用find可迭代对象的spliterator()方法,然后进行流操作,映射为字符串并收集:
StreamSupport.stream(collection.find().spliterator(), false)
        .map(Document::toJson)
        .collect(Collectors.joining(", ", "[", "]"))

请注意,并行流不适用于Mongo结果,因此请将parallel标志保持为false

StreamSupport.stream(...).collect(...)方法是否保留了初始集合.find(...)的顺序/排序? - bastien enjalbert
1
@bastienenjalbert 是的 - mtj

0
请注意,this answer可能会导致资源泄漏,因为在collection.find().spliterator()内部创建的迭代器从未关闭,需要关闭才能将连接返回到连接池中。 要解决这个问题,您需要按照以下方式进行操作:
try (MongoCursor<Document> cursor = collection.find().iterator()) {
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(cursor,0), false)
                        .map(Document::toJson)
                        .collect(Collectors.toList())
}

或者不使用流:

return collection.find()
                 .map(Document::toJson)
                 .into(new ArrayList<>());

在这种情况下,资源(MongoCursor)也会被正确关闭。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接