我有一个mongo数据库查询,返回10000多条记录。对于商业服务,我想以GSON(谷歌JSON)格式返回记录。以下是代码段。
String mongoClientURI = null;
mongoClientURI = "mongodb://" + dbUser + ":" + pwd + "@" + host + ":" + port + "/" + databaseName;
MongoClient client = new MongoClient(new MongoClientURI(mongoClientURI));
MongoDatabase db = client.getDatabase(databaseName);
// Find query returns more than 10K records
FindIterable<Document> dbResult = db.getCollection("mycollection").find();
// This line takes too much time & CPU
List<Document> result = getDocumentArray(dbResult);
// This line takes too much time & CPU
JsonArray finalResult = getJSONArray(result);
public static List<Document> getDocumentArray(FindIterable<Document> input) {
List<Document> output = new ArrayList<Document>();
for (Document doc : input) {
output.add(doc);
}
return output;
}
public static JsonArray getJSONArray(Iterable<Document> docs) {
JsonArray result = new JsonArray();
if (docs == null) {
return result;
}
for (Document doc : docs) {
JsonObject jsonObject;
JsonParser parser = new JsonParser();
try {
jsonObject = parser.parse(doc.toJson()).getAsJsonObject();
result.add(jsonObject);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
return result;
}
问题是从MongoDB获取数据到GSON数组时需要花费大量时间和CPU周期。有人可以告诉我从mongodb获取大数据集到gson格式的有效方法是什么?
通常我会获得大约10k到20K的记录,(最多50K)。我需要归还所有这些。我的UI组件需要一次性中的所有记录来呈现数据。通常人们使用带有分页的数据网格,因此一次性没有太多记录,但在我的情况下,我有地图组件,它取得所有记录和动态创建一组对象。
非常感谢任何帮助。
Atul Sureka
答案 0 :(得分:1)
有效的方法是不要一次性返回所有文档,而是使用skip()
和limit()
函数来实现分页。如果你的收藏品让我们说了一百万份文件,你最终会在内存中找到一个大的List
,你甚至可能不需要一次性在UI上显示所有文件。
以下是如何实现分页:
1st Call : db.getCollection("mycollection").find().limit(10);
2nd Call : db.getCollection("mycollection").find().skip(10).limit(10);
3rd Call : db.getCollection("mycollection").find().skip(20).limit(10);
skip
驱动页码,而limit
驱动每页的项目。您也可以使用sort
来定义排序(here's文档)。
另一种方法是使用排队机制或流式传输来滚动cursor
中的所有文档并推送到队列/客户端。
<强>更新强>
您可以采取以下措施来加快现有实施的速度:
Iterable
转换为parallelStream
以更快地处理文档(请查看this以及如何将Iterable
转换为stream
的答案0} JsonParser
实例。创建一个实例并将其用于所有文档。Xmx
值答案 1 :(得分:0)
您是否在mongoDB中的列上添加了索引?它有助于更快地获取/读取查询。默认索引位于_id列。
另一种方法是根据特定标准找到,尝试将其拆分为2
db.getCollection("mycollection").find({ dept: "grocery", category: "chocolate" });
db.getCollection("mycollection").find({ dept: "sales", category: "honey" });
并稍后合并此结果