4

我有一个数据库,用于存储大量数据并生成图表视图。我没有返回图表的所有数据,而是只返回预定义数量的样本。我目前这样做的方式是在 mongo 上使用 map/reduce 作业,但我不知道我这样做的方式是否非常有效,它需要 14 秒并将 CPU 固定在有超过 89000 个样本的图表上例子。

下采样通过计算“分辨率”来工作,即(总点数)/(所需的样本数)。然后它使用范围变量保持外部计数和索引。然后它基本上查看每个点,并根据分辨率和计数/索引变量的当前状态决定是否将其包含在结果列表中。

这工作正常,但速度很慢并且可能不可扩展。我想知道例如只返回所有点并在 ruby​​ 中进行下采样是否会更好,或者也许有更好的方法。

4

1 回答 1

3

万一有人感兴趣,这是我想出的解决方案。由于 mongodb 的一些限制,我花了一段时间才弄清楚,但它工作得很好,比我当前的 map reduce 解决方案快 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)) 来伪造它,这给了你除法的整数部分。

这很有效,并且可以让你做一些事情,比如平均块,而不是仅仅选择第一个,很容易。

于 2013-03-15T05:46:29.433 回答