0

mongodb のデータベースには複数の時系列があり、他のフィールドの中でも「ticker」、「time」、および「close」フィールドがあります。

> db.bbticks.find().limit(2)
{ "_id" : ObjectId("522b2cf7d4236309a57c8f96"), "close" : 1.9432, "high" : 1.9433, "low" : 1.9426, "open" : 1.9427, "source" : "HIST", "systime" : ISODate("2013-09-07T13:41:13.383Z"), "ticker" : "USDTRY Curncy", "time" : ISODate("2013-08-01T15:14:00Z"), "type" : "BAR", "value" : 1.9432 }
{ "_id" : ObjectId("522b2cf7d4236309a57c8f97"), "close" : 1.9425, "high" : 1.9433, "low" : 1.9425, "open" : 1.9432, "source" : "HIST", "systime" : ISODate("2013-09-07T13:41:13.383Z"), "ticker" : "USDTRY Curncy", "time" : ISODate("2013-08-01T15:15:00Z"), "type" : "BAR", "value" : 1.9425 }

タイムスタンプは分単位です。ティッカーには複数のタイムゾーンが表示されているため、たとえば、MEXBOL Mexical 株式市場は UTC 13 時 30 分からのみ開いていますが、FTSEMIB イタリア株式市場は UTC 07 時 00 分から開いています。すべての時系列をダウンさせたいのですが、それらすべてが持っているタイムスタンプのみです。次に例を示します。

> db.bbticks.find({ticker: "FTSEMIB Index", type: "BAR", time: {$gte: ISODate("2013-08-01")}}, {_id: 0, ticker: 1, time: 1, close: 1}).sort({time: 1}).limit(5)
{ "close" : 16565.04, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T07:00:00Z") }
{ "close" : 16585.56, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T07:01:00Z") }
{ "close" : 16583.29, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T07:02:00Z") }
{ "close" : 16578.95, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T07:03:00Z") }
{ "close" : 16587.16, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T07:04:00Z") }
> db.bbticks.find({ticker: "MEXBOL Index", type: "BAR", time: {$gte: ISODate("2013-08-01")}}, {_id: 0, ticker: 1, time: 1, close: 1}).sort({time: 1}).limit(5)
{ "close" : 41101.39, "ticker" : "MEXBOL Index", "time" : ISODate("2013-08-01T13:30:00Z") }
{ "close" : 41099.25, "ticker" : "MEXBOL Index", "time" : ISODate("2013-08-01T13:31:00Z") }
{ "close" : 41126.17, "ticker" : "MEXBOL Index", "time" : ISODate("2013-08-01T13:32:00Z") }
{ "close" : 41137.03, "ticker" : "MEXBOL Index", "time" : ISODate("2013-08-01T13:33:00Z") }
{ "close" : 41173.89, "ticker" : "MEXBOL Index", "time" : ISODate("2013-08-01T13:34:00Z") }

ご覧のとおり、2013 年 8 月 1 日以降のティックでは、FTSEMIB は 07:00 に始まり、MEXBOL は 13:30 に始まります。13 時 30 分以降の FTSEMIB のデータも存在します。

> db.bbticks.find({ticker: "FTSEMIB Index", type: "BAR", time: {$gte: ISODate("2013-08-01T13:30:00")}}, {_id: 0, ticker: 1, time: 1, close: 1}).sort({time: 1}).limit(5)
{ "close" : 16739.41, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T13:30:00Z") }
{ "close" : 16748.21, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T13:31:00Z") }
{ "close" : 16750.76, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T13:32:00Z") }
{ "close" : 16747.89, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T13:33:00Z") }
{ "close" : 16746.66, "ticker" : "FTSEMIB Index", "time" : ISODate("2013-08-01T13:34:00Z") }

したがって、基本的に、両方のティッカーに「時間」フィールドが存在する場合は、それらの終値のみが返されるようにします。クエリには (2 つだけでなく) 複数の時系列が存在する可能性があり、そうでなければ連続した系列のブロック内に値が欠落している可能性があります (たとえば、8 月 1 日の 14 時 31 分に、1 つの系列がその時間の値を持たない可能性があります。その場合、その時間のシリーズを返す必要はありません)。

基本的に、時系列を比較したいのですが、すべてのタイムスタンプに対してのみ返される系列が必要です。

最後に、できれば Map Reduce ではなく、集約パイプライン フレームワークを使用することをお勧めします。

4

1 に答える 1

1

以下が達成したいことと一致しているかどうかを確認してください。

db.bbticks.aggregate(
[
 { $match: { time: { $gte: ISODate("2013-08-01") } } },
 { $group: { _id: "$time", count: {$sum: 1}, tickers: { $push: { "ticker": "$ticker" , "close": "$close" } } } } ,
 { $match: { count: { $gt: 1 } } }
]
)

- 壊す -

map-reduce については、以下を試すことができます (あまりエレガントではありません。もっと良い方法があると思いますが、始めるためのアイデアがいくつかあります)。また、これは成長する時系列になるため、インクリメンタル map-reduce ( http://docs.mongodb.org/manual/tutorial/perform-incremental-map-reduce/ ) を使用する可能性があります。しかし、以下はあなたにいくつかのアイデアを与えることができます(私が言ったように、それは醜いです---そして、私の最後のfindステートメントではなく、2番目のmap-reduce操作を実行する方が良いかもしれませんが、あなた次第です)。

var mapFunction = function() {
                      var key = this.time

                      var value = { tickers: [
                                                { ticker: this.ticker, close: this.close } 
                                             ] };

                      emit( key, value );
                  };

var reduceFunction = function(keyObject, valuesArray) {
                     var reducedValue = { tickers: [] };

                     for (var idx = 0; idx < valuesArray.length; idx++) {
                        reducedValue.tickers.push( valuesArray[idx].tickers[0] )
                     }

                     return reducedValue;
                  };


db.bbticks.mapReduce( mapFunction,
                      reduceFunction,
                      {
                        out: "mr_interim_results",
                        sort: { time: 1 },
                        query: {
                                 time: {$gte: ISODate("2013-08-01") }
                               },
                      }
                   )

db.mr_interim_results.find( { 'value.tickers': { $not: { $size: 1 } } }  )
于 2013-09-08T20:47:07.780 に答える