Java MongoDB:BigData上的FindTable
我在Ubuntu14上使用Java7和MongoDB3.0的java驱动程序 我已经使用mongoDB开发了一个BigData项目几个月了。在分析了我的项目绩效后,我发现了一个瓶颈。因此,我的一些查询将包含数百万个文档。我得到的结果是FindItemable类型。当我执行计算时,我必须遍历每个文档,mongoDB文档告诉我执行iterable.forEach。因此,我的代码如下所示: 这是我的疑问之一:Java MongoDB:BigData上的FindTable,java,mongodb,Java,Mongodb,我在Ubuntu14上使用Java7和MongoDB3.0的java驱动程序 我已经使用mongoDB开发了一个BigData项目几个月了。在分析了我的项目绩效后,我发现了一个瓶颈。因此,我的一些查询将包含数百万个文档。我得到的结果是FindItemable类型。当我执行计算时,我必须遍历每个文档,mongoDB文档告诉我执行iterable.forEach。因此,我的代码如下所示: 这是我的疑问之一: FindIterable<Document> iterable = db.get
FindIterable<Document> iterable = db.getCollection(dbName).find(
new Document()
.append("timestamp", new Document()
.append("$gte", startTime)
.append("$lte", endTime))
.append("latitude", new Document()
.append("$lte", maxLat))
.append("latitude", new Document()
.append("$gte", minLat))
.append("longitude", new Document()
.append("$lte", maxLong))
.append("longitude", new Document()
.append("$gte", minLong))
);
然后,我将该iterable传递给我的createLayer函数
protected double[][] createLayer(FindIterable<Document> iterable) {
int x = (int) ((maxLat * 100000) - (minLat * 100000));
int y = (int) ((maxLong * 100000) - (minLong * 100000));
final double[][] matrix = new double[x][y];
iterable.forEach(new Block<Document>() {
@Override
public void apply(final Document document) {
//System.out.println(document.get("longitude")+" - "+ document.get("latitude"));
int tempLong = (int) ((Double.parseDouble(document.get("longitude").toString())) * 100000);
int x = (int) (maxLong * 100000) - tempLong;
int tempLat = (int) ((Double.parseDouble(document.get("latitude").toString())) * 100000);
int y = (int) (maxLat * 100000) - tempLat;
matrix[y][x] += 1;
}
});
return matrix;
}
当我的iterable包含350万个文档时,我的运行时间约为80秒。如果删除次要计算,运行时间约为76秒。显然,我的计算不是这里的瓶颈,而是通过每个文档的迭代
我看了这篇文章,但由于我没有使用Java8,lambda操作是不可用的
所以,我的问题是,iterable.forEach是迭代一大组文档的最快方法吗?FindTable到底包含什么?iterable.forEach是否因为查询数据库而变慢?lambda快多了
编辑:我用我的计算更新了方法。这不重要,因为当我删除它时,运行时间仍然很高,如上所述。不确定您在这里问什么。我假设您说查询选择本身返回一个包含您指定的数字的数据集,但真正的问题是您在对结果做什么,即小计算。如果你意识到这是一个瓶颈,那么也许你应该解释一下那些小的计算实际上打算做什么。可能有一种更好的处理方法,而不是将所有结果从服务器获取到客户端。这将大大减少所花费的时间。请看我的编辑,我的计算不是这里的瓶颈。我必须遍历每个文档。也许你应该解释一下你的代码要做什么。乍一看,您似乎基本上是根据纬度和经度组合进行分组,以计算发生率。是这样,还是至少是这样?如果是这样,那么服务器上某种类型的聚合操作似乎比迭代集合更符合逻辑。如果您将所有这些数据拉到客户端只是为了计算类似的内容,那么这当然是最大的性能消耗。您对代码的理解是正确的。聚合也是我一直在考虑的一个解决方案,很好的选择。这个问题的目的是询问在执行iterable.forEach时实际发生了什么,以及是否有更快的方法遍历每个文档。没有更快的方法。关键在于数据传输。如果包含到服务器的聚合,那么就没有这种开销。收益是巨大的。如果您有处理其他数据库(如关系型SQL数据库)的概念,那么区别就像一个小组一样显而易见,要求收集所有文档,然后自己总结它们。事实上,您甚至可以假设为什么要发送查询条件?,这时您可以测试每个结果,看看它是否符合您希望在客户端中发送到数据库的条件。数据库支持这一点是有原因的。