0

私のコレクションには、経時的な為替レートが含まれています。グラフを表示したいのですが、1 時間ごとに 1 つの値だけを知る必要があります。ただし、私のデータははるかに密度が高く、1 秒ごとに 1 レコード程度です。

1 時間に 1 つだけ残すレコードの密度を下げるにはどうすればよいですか。平均は必要ありません。各時間の記録で十分です。

{
    "_id" : ObjectId("52112613b45b5d057589009e"),
    "date" : ISODate("2013-08-18T19:52:51.873Z"),
    "rate" : 0.00007382007912027975,
    "symbol" : "XAU=X"
}
{
    "_id" : ObjectId("52112613b45b5d057589009f"),
    "date" : ISODate("2013-08-18T19:52:52.273Z"),
    "rate" : 0.00007382007912083746,
    "symbol" : "XAU=X"
}

回答ではパフォーマンスを考慮してください。

ありがとうございました。

4

2 に答える 2

1

集約フレームワークを使用できますが、パフォーマンスを本当に気にする場合は、事前に集約されたコレクションに履歴レコードを保持することを検討する必要があります。

first per hour 以外のレコードを使用できる場合は、$sortフェーズを省略して に直接進むことができます$group

pipeline =  [
    {
        "$sort" : {
            "date" : 1
        }
    },
    {
        "$group" : {
            "_id" : {
                "symbol" : "$symbol",
                "hour" : { "$hour" : "$date" },
                "day" : { "$dayOfMonth" : "$date" },
                "month" : { "$month" : "$date" },
                "year" : { "$year" : "$date" }
            },
            "rate" : { "$first" : "$rate" },
            "symbol" : { "$first" : "$symbol" },
            "date" : { "$first" : "$date" }
        }
    },
    {
        "$project" : {
            "date" : 1,
            "symbol" : 1,
            "rate" : 1,
            "_id" : 0
        }
    }
]

db.foo.aggregate(pipeline)
于 2013-11-27T03:25:58.883 に答える
1

他のいくつかのオプション

  1. スキーマ - 1 時間ごとの要約ドキュメントを作成して保存します。新しいドキュメントを追加すると、「毎時」エントリが更新されます。この手法は、合計、平均などを行う場合にも効果的です。また、この要約を維持するためのオーバーヘッドは、すべての操作で償却されます。
  2. クエリ - どの行でも問題ないため、日付フィールドと limit(1) に基づいて時間範囲のクエリを実行します

上記のパイプライン アプローチの問題は、クエリが最適化されておらず、コレクション内のすべてのドキュメントをスキャンすることです。より効率的にするために、クエリに日付範囲を追加します。また、パイプラインには 32MB のハード制限があります。それ以上のデータがある場合、集計は機能しません。

于 2013-11-27T03:34:26.167 に答える