2017-09-12 6 views
0

次の時系列データをmongodbに持っていますMongoDBで時系列データを効率的に更新するには

チャンネルコレクションには各チャンネルに関するデータがあります。 各チャネルドキュメントには、そのチャネルの時系列データを保持するjson配列であるリアルタイムデータ - > rtDataがあります。

db.channels.findは({})。かなり()と同様の構造に

{ 
    channelName:"ABC", 
    rtData:[ 
     { 
     ts:ISO_DATE(timestamp), 
     data:[12, 14] 
     }, 
     { 
     ts:ISO_DATE(timestamp), 
     data:[12, 14] 
     }, 
     { 
     ts:ISO_DATE(timestamp), 
     data:[12, 14] 
     }, 
     . 
     . 
     . 
    }, 
    { 
    channelName:"NBC", 
    rtData:[ 
     { 
     ts:ISO_DATE(timestamp), 
     data:[12, 14] 
     }, 
     { 
     ts:ISO_DATE(timestamp), 
     data:[12, 14] 
     }, 
     { 
     ts:ISO_DATE(timestamp), 
     data:[12, 14] 
     }, 
     . 
     . 
     . 
    }, 

を与え、4秒ごとに私は1つまたは複数のチャネル

{ 
    ts: ISO_DATE(timestamp), 
    data: [14,15] 
} 

の更新されたレコードを取得しますこのレコードは、そのチャンネルのrtData配列でプッシュ/更新する必要があります。

だから何私がやったことはこれに似たものだった -

channels.findOne({query}, function(channel) { 
    channel.rtData.push(newData); 

    channels.findAndModify({query}, {$set:{rtData: channel.rtData}}, 
    function({})) 
}) 

、チャンネルを探すrtData配列にデータをプッシュして検索を行うと、変更します。

これは、データ量が少ない場合に動作するようです。しかし、1つのチャンネルのrtData配列に近い50Kの要素がある場合、アプリケーションはそれを処理できません。

時系列データを効率的に更新できますか?

答えて

1

あなたはあなたのモデルimhoを埋め込んでいます。 MongoDBのBSONドキュメントには16MBのサイズ制限があることに注意してください。 さらに、ドキュメントを変更するには、単純にドキュメントを挿入するよりも時間がかかります。 ObjectID contains a timestamp already以来

、さらにはあなたにそれぞれ入力された値に対して一意性を与え、

{ 
    _id: new ObjectID(), 
    channelName: "NBC", 
    value: [14,15] 
} 

のようなものは非常に効率的にデータを挿入します。

secs = Math.floor(Date.Now()/1000) 
hexSecs = secs.toString(16) 
id = ObjectId(hexSecs+"0000000000000000") 

db.values.find({"_id":{$lt:id}}) 

この例ではあなたよりもすべてのエントリ古いを与えるだろう:日付に基づいて照会のために、あなたはのObjectIDはエポックからの秒を含む4バイト値の16進表現で始めているし、そうでない場合は、単調に増加しているあなたの利点に使用します時間Date.Now()が呼び出されました。もちろん、開始日と終了日を変換する同じ方法を使用して、範囲を照会することができます。詳細については、the according entry "Popping time stamps into ObjectIds" on Kristina Chodorow's blog

を参照してください。残りのクエリと集計は明白でなければなりません。

関連する問題