我有一个数据库,我存储了大量数据并为图形生成视图。我没有返回图表的所有数据,而只返回预定义数量的样本。我目前这样做的方式是在mongo上使用map / reduce作业,但我不知道我这样做的方式是否非常有效,需要14秒并且在图表上固定CPU,其中包含超过89000个样本例。
下采样通过计算“分辨率”,即(总的#个点数)/(期望的样本数)来工作。然后使用范围变量保持外部计数和索引。然后它基本上查看每个点,并根据分辨率和计数/索引变量的当前状态决定是否将其包含在结果列表中。
这很好用,但速度很慢,可能无法扩展。我想知道是否更好的例如只返回所有的点并在ruby中进行下采样,或者可能有更好的方法。
答案 0 :(得分:3)
如果有人感兴趣,这就是我提出的解决方案。由于mongodb的一些限制,我花了一段时间才弄明白,但是效果非常好,比我目前的地图缩减解决方案快了10倍。
这是聚合代码:
db.data.aggregate(
{$match: {$and: [{graph_id: gid}, {"x.value": {$gt: start, $lt: stop}}]}},
{$project: {x: 1, y: 1, series: 1, chunk: {$subtract: [{$divide: ["$x.value", step]}, {$mod: [{$divide: ["$x.value", step]}, 1]}]}}},
{$group: {
_id: {
chunk: "$chunk",
series: "$series"
},
series: {$first: "$series"},
x: {$first: "$x"},
y: {$first: "$y"},
}
},
{$sort: {"x.value": 1}}
)
此解决方案会对数据进行分块。我想做类似int(x.value / step)的东西,但是mongodb没有整数数学运算符。所以我不得不用((x.value / step) - ((x.value / step)%1))来伪造它,它给出了除法的整数部分。
这很好用,可以让你做一些事情,比如平均块,而不是只选择第一块,非常容易。