【发布时间】:2011-01-27 18:32:40
【问题描述】:
我正在尝试使用 mongodb java 驱动程序从集合中计算平均值,如下所示:
DBObject condition =
new BasicDBObject("pluginIdentifier", plugin.getIdentifier());
DBObject initial = new BasicDBObject();
initial.put("count", 0);
initial.put("totalDuration", 0);
String reduce = "function(duration, out) { out.count++;
out.totalDuration+=duration.floatApprox; }";
String finalize = "function(out) { out.avg = out.totalDuration.floatApprox /
out.count; }";
DBObject avg = durationEntries.group(
new BasicDBObject("pluginIdentifier", true),
condition, initial, reduce, finalize);
System.out.println(avg);
“duration”是一个NumberLong(在java中,它是一个Long,可能是java驱动程序转换的)。 经过一番搜索,我发现为了提取数字,使用 .floatApprox 是一种方法,这也适用于 mongodb 控制台:
> db.DurationEntries.findOne().duration.floatApprox
5
但是,运行上面的 java 代码不会计算平均值,而是返回这个值
[{"pluginIdentifier":"dummy", "count":7.0, "totalDuration":NaN, "avg":NaN}]
我尝试了几种变体,使用和不使用 .floatApprox,但到目前为止只能获得一些奇怪的字符串连接。
我的问题是:我做错了什么/我应该如何计算一个 NumberLong 列的平均值?
【问题讨论】:
-
这里的关键是您想让 mongo 进行平均而不是将列数据拉入 Java 吗?您确定您的持续时间中没有意外包含任何非数字数据吗?
-
是的,这就是我的意图,在数据库中而不是在内存中进行计算(因为当我有很多条目时,我认为我的 JVM 会耗尽内存)。是的,确实可能存在非数字数据,因为可能存在“空”平均条目 - 我会检查一下
-
如果你想要的只是一个平均值,那么我认为它不应该占用大量内存,因为你不需要将每个条目保存在内存中,只需一个总和和一个计数.我对 Mongo 不够熟悉,无法确切说明如何操作,但是如果您可以从查询中批量处理结果集,那么您可以一次处理一个子集。
标签: java mongodb mapreduce grouping