我正在评估ArangoDB(版本3.2.4)作为MongoDB的替代品。我们有一个包含2.700.000文档的庞大集合。明年这个系列将增加(近4.000.000份文件)。
如果我想使用Java驱动程序(版本4.2)从该集合中读取数据,则游标需要花费大量时间来获取该数据。时间取决于获取文档的大小,这意味着,如果我想获取所有文档,光标需要大约10分钟来获取数据:
AQL:
for doc in myHugeCollection
RETURN { "name": doc.name }
Java代码:
AqlQueryOptions aqlQueryOptions = new AqlQueryOptions();
aqlQueryOptions.batchSize(500);
aqlQueryOptions.count(false);
aqlQueryOptions.cache(true);
ArangoCursor<MyHugeCollection> arangoCursor = arangoDatabase.query(
aqlQuery,
new HashMap<>(),
aqlQueryOptions,
MyHugeCollection.class);
这将需要大约10分钟,直到我能够通过光标访问数据。因为我将批量大小设置为500,我的期望是一个快速响应,因为获取前500个结果非常快。
修改后的AQL获取前500个文档:
for doc in myHugeCollection
limit 500
RETURN { "name": doc.name }
此查询大约需要20毫秒。
所以,我的问题是我做错了什么?如何在不等待光标的情况下访问大型集合中的数据?
答案 0 :(得分:1)
这取决于您访问光标的方式。
当您将其转换为List
时,将获取结果的每个文档。
List<MyHugeCollection> asList = arangoCursor.asListRemaining();
当您使用next()
或forEachRemaining()
(需要Java 8)进行迭代时,您可以在从数据库中提取下一批文件之前处理前500个文档。
for (; arangoCursor.hasNext();) {
MyHugeCollection doc = arangoCursor.next();
// TODO
}
或
arangoCursor.forEachRemaining(doc -> {
// TODO
});
答案 1 :(得分:0)
似乎你需要一些Async invocaiton,这样你的代码就不会等待返回整个数据集,但是可以在返回一些初始数据后开始工作。 您是否尝试过Java异步驱动程序(https://github.com/arangodb/arangodb-java-driver-async)?我认为你应该能够在Arango获得第一个结果集后立即开始做一些工作...... 尝试在异步驱动程序手册中查找此部分:
db.query(query, bindVars, null, MyObject.class).thenAccept(cursor -> {
cursor.forEachRemaining(obj -> {
System.out.println(obj.getName());
});
});
另一个提示是尝试Java Driver提供的VelocyPack对象。但我不确定它们是否与您的用例可能需要的异步一样。