4

大量のデータを保存し、グラフのビューを生成するデータベースがあります。グラフのすべてのデータを返す代わりに、定義済みの数のサンプルのみを返します。私が現在これを行う方法は、mongo で map/reduce ジョブを使用することですが、これを行う方法が非常に効率的かどうかはわかりません。14 秒かかり、89000 を超えるサンプルを持つグラフに CPU をペグします。例。

ダウン サンプリングは、「解像度」、つまり (ポイントの総数) / (目的のサンプル数) を計算することによって機能します。次に、スコープ変数を使用して外部のカウントとインデックスを保持します。次に、基本的に各ポイントを見て、解像度とカウント/インデックス変数の現在の状態に基づいて、結果リストに含めるかどうかを決定します。

これは問題なく動作しますが、かなり遅く、おそらくスケーラブルではありません。たとえば、すべてのポイントを返してルビーでダウンサンプリングを行う方が良いか、それとももっと良い方法があるかどうか疑問に思っています。

4

1 に答える 1

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)) で偽造する必要がありました。これにより、除算の整数部分が得られます。

これはうまく機能し、最初のチャンクを選択するだけでなく、チャンクの平均化などを非常に簡単に行うことができます。

于 2013-03-15T05:46:29.433 に答える