2017-12-18 13 views
1

私はMongoのに非常に新しいですし、ちょうど私が時系列データのスキーマを実装していて、パターンを試すことを計画しています...中核となる概念のまわりで私の頭を取得していますここに示唆された:MongoDB as a Time Series Database、これはまた、いくつかのMongoのプレゼンテーションにも登場しています。のMongoDB - 時系列サブ文書の範囲クエリ

私は、スキーマを理解しますが、難易度1は、日付の範囲のためにそれを照会する方法をワークアウトを持っています。より具体的には、上記のリンクでスキーマをクエリする方法の例を示して、複数の時間/日にわたる1分の系列を取得することはできますか?理想的には、Mongo以外での後処理は必要ありません。

Mongoのドキュメント凝集パイプラインは、処理アレイではなく、ネストされたサブ文書とほとんど関係現れる... TIA。

編集:私は解決しようとしている特定の問題に多くの明快さを追加するには...

のは、私は次のスキーマを使用して、一日一の親文書で、1分間隔でデータを格納していましょう(上記にリンクされているポストから切り取ら):フォームのクエリを満たすために最も効果的/効率的な方法だろう

{ 
    timestamp_hour: ISODate("2013-10-10T23:00:00.000Z"), 
    type: “spot_EURUSD”, 
    values: { 
    0: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343}, 
    1: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343}, 
    …, 
    22: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343}, 
    23: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343} 
    } 
} 

何:「私の値の時系列リストを与える、毎分1は、上の開始します2013- 09-25午後1時37分、午後2時56分に2013-10-15で終了しますか?あなたはそれが正しい方向にあなたを指している必要がありましたリンク上@jtromansからのコメントがあります

答えて

0

は...あなたがダウン満たすために必要な最高の解像度に応じてデータを「ビニング」継続すべきです基準

だからあなたは次のようなスキーマを持っていると仮定すると:

{ 
    timestamp_hour: ISODate(...), 
    values: { 
     0: {}, 
     1: {}, 
     ... 
     59: {} 
    } 
} 

その後、あなたはwは、毎分サブドキュメントを持っていますHICHあなたは、たとえば、かなり単純に(4分内のすべての時間を見つけるためにあなたの照会を満たすことができます:

collection.find({}, {"values.3": 1}) 

これだけの投影のみに興味があります分の値をフィルタリングすることはそうでない場合は、フルなので。テーブルスキャンの場合、検索を制限するためにtimestamp_hourフィールドに日付範囲を含めることをお勧めします。あなたが好きな場合は、より良い、たとえば、あなたが期待するフォーマットに合わせて値を投影する集約を使用することができます。

collection.aggregate([ 
    {$project: {val: "$values.1"}} 
]) 

あなたは時間の時間、秒、または他の部分にフィルタリングできるようにする必要がある場合は、スキーマ内のビンまたはキーのいずれかが必要です。秒と分のビニング:

{ 
    timestamp_hour: ISODate(...), 
    minutes: { 
     0: { 
      seconds: { 
       0: ... 
      } 
     }, 
     ... 
    } 
} 

彼らはインデックスを作成してフィルタリングすることができますので、キーとして他の値を追加:私はここに、文書ごとの時間的なアプローチを使用しました

{ 
    timestamp_hour: ISODate(...), 
    hour_of_day: 0, 
    day_of_month: 1 
    minutes: { 
     ... 
    } 
} 

注意を、あなたはその場合、あなたのデータや要件に基づいて決定する必要がありますあなたに合ったり、毎分、1日あたりの文書が必要な場合

編集:ここでは、より良い試合、編集された質問の例です:

db.ts.aggregate([ 
    { 
     $match: { 
      timestamp_hour: {$lte: {ISODate("2013-09-25")}, $gte: {ISODate("2013-10-15")}} 
     } 
    }, 
    { 
     $project: { 
      hours: {$objectToArray: "$values"} 
     } 
    }, 
    { 
     $unwind: "$hours" 
    }, 
    { 
     $project: { 
      hour_index: "$hours.k", 
      minutes: {$objectToArray: "$hours.v"} 
     } 
    }, 
    { 
     $unwind: "$minutes" 
    }, 
    { 
     $project: { 
      reconstructed_date: {$dateFromParts: { 
       year: {$year: "$timestamp_hour"}, 
       month: {$month: "$timestamp_hour"}, 
       day: {$day: "$timestamp_hour"}, 
       hour: "$hour_index", 
       minute: "$minutes.k", 
      }} 
      value: "$minutes.v" 
     } 
    }, 
    { 
     $match: { 
      reconstructed_date: {$lte: {ISODate("2013-09-25T13:37:00.000Z")}, $gte: {ISODate("2013-10-15T14:56:00.000Z")}} 
     } 
    } 
]) 

私はそれはあなた次第です、右この1でタイムゾーンを取得しようとしていませんよ!

+0

あなたの答えをありがとうが、私が探しているものは、あなたが記述したものより簡単かもしれないと思います。私はちょうどバニラの日付範囲のクエリを、特定のタイムスロットのフィルタではないと思います。私は明確にするために私の質問を編集しました。何かご意見は? – stephenrs

+0

ああ、そうです。 '$ project'ステージで' $ objectToArray'を使う必要がありますので、後で '$ unwind'を使うことができます(アンワインドは配列に対してのみ動作します;この特定の理由でオブジェクトから配列への切り替えが必要な場合がありますあなたの集合体が乱雑になるので)。特定のものの代わりにすべての分を取得し、その分(何らかの値が値の代わりに配列またはサブドキュメントである場合、最初の項目)を選択すると、これを_twice_する必要があります。 –

+0

時間範囲のクエリも複雑になるでしょう - 'timestamp_hour'フィールドに最初の' $ match'ステージが1つ必要です(ドキュメントセットを適切なサイズにするために、境界に注意する必要があります)最初の/最後の日に不要な値を除外するための最終的な '$ match'ステージを持つように、時/分/秒の値で新しいフィールドを作成する' $ project'ステージが必要になります。全体的に見て、かなり複雑になり、実績のあるデータセットでテストを実行して、クエリのパフォーマンスが正常になるようにしたいと考えています。 –

関連する問題