2016-04-08 11 views
2

私はMongoDBを使用してギャップを持つ時系列データを保存します。各文書は1つの項目に属し、複数の測定点の変更を保持します。 各計測点にIDがありますので、以下の例ではID番号some-id-XXXを使用しました。MongoDB Project /集計すべてのサブドキュメントを取得する最新の配列エントリ

アプリケーションは、特定のサブ文書に変更のみを書き込みます。したがって、一連のギャップの可能性があり、APPはドキュメント全体をロードして変更をチェックし、変更を加えたサブドキュメント(たとえば"some-id-1")を更新します。

{ 
    "_id": "XXX-DAY_OF_YEAR", 
    "date": null /* A date used for the TTL index */, 
    "series" : { 
     "some-id-1" : [ 
      { 
       "ts" : 1457959837, 
       "value" : 385, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1457959837, 
       "value" : 385, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458286255, 
       "value" : 380, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458346606, 
       "value" : 375, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458381111, 
       "value" : 368, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458381461, 
       "value" : 365, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458606338, 
       "value" : 385, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458606338, 
       "expired": true 
      } 
     ], 
     "some-id-2" : [ 
      { 
       "ts" : 1439802083, 
       "value" : 430, 
       "meta" : "some meta info …" 
      } 
     ], 
     "some-id-42" : [ 
      { 
       "ts" : 1457545167, 
       "value" : 518, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458483441, 
       "value" : 1034, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458518979, 
       "value" : 518, 
       "meta" : "some meta info …" 
      } 
     ], 
     "some-id-1337" : [ 
      { 
       "ts" : 1458017854, 
       "value" : 361, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458050773, 
       "value" : 384, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458115173, 
       "value" : 383, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458143968, 
       "value" : 382, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458176011, 
       "value" : 381, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458212600, 
       "value" : 384, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458245285, 
       "value" : 383, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458277108, 
       "value" : 382, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458309875, 
       "value" : 379, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458338258, 
       "value" : 378, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458374471, 
       "value" : 374, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458405856, 
       "value" : 364, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458435330, 
       "value" : 363, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458471185, 
       "value" : 362, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458500103, 
       "value" : 361, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458535837, 
       "value" : 360, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458568805, 
       "value" : 364, 
       "meta" : "some meta info …" 
      }, 
      { 
       "ts" : 1458633188, 
       "value" : 384, 
       "meta" : "some meta info …" 
      } 
     ] 
    } 
} 

このapprocachの問題は、変更またはギャップのチェックに必要なドキュメント全体のロードによって生成されるトラフィックです。

最新の値(配列の最後の値)しか取り出せない場合、トラフィックはスラッシュアップされます。

{ 
    "series" : { 
     "some-id-1" : [ 
      { 
       "ts" : 1458606338, 
       "expired": true 
      } 
     ], 
     "some-id-2" : [ 
      { 
       "ts" : 1439802083, 
       "value" : 430, 
       "meta" : "some meta info …" 
      } 
     ], 
     "some-id-42" : [ 
      { 
       "ts" : 1458518979, 
       "value" : 518, 
       "meta" : "some meta info …" 
      } 
     ], 
     "some-id-1337" : [ 
      { 
       "ts" : 1458633188, 
       "value" : 384, 
       "meta" : "some meta info …" 
      } 
     ] 
    } 
} 

私がIDを知っている限り、最近の最近のエントリを取得するために投影を使用することができます。

db.Series.find( 
{ "series.some-id-42" : { $exists: true } }, 
{ "series.some-id-42.$": -1} 
) 

しかし、変更にはギャップが含まれている可能性があるため、ターゲットシリーズのドキュメントで発生しているすべてのIDはわかりません。

これを集約フレームワークまたは巧妙な投影法でアーカイブする可能性はありますか?

私の唯一のアイデアは、よりコンパクトな形での最近の値を格納し、プロジェクトのみ{last_recent: 1}さ:

{ 
    "recent": { 
     "some-id-1" : 0, 
     "some-id-2" : 430, 
     "some-id-42" : 518, 
     "some-id-1337" : 384 
    } 
    "series" : { /* … */ } 
} 

しかし、私はこの問題のために、よりエレガントな解決策があると願っています。

+0

あなたが「ダイナミック」であることを '「いくつかの-ID-X」'の部分を期待しているならば、それは単に集約フレームワークで発生するつもりはありません。実際には、このように複数の値を格納するためにこれを使用するのはあまり実用的ではないだけでなく、「名前付きキー」の使用の両方で、非常に優れた設計でもありません。これは、全体の構造が私が見ることができる意図された使用のための良いアイデアのように見えないので、これは実際に再設計することができます。 –

答えて

0

IDのフィールド名にデータを格納するという問題があります。

スキーマは、おそらく次のようになります。

{ 
    "series": [ 
     { 
      "id": 1, 
      "content": [ 
       { 
        "ts": 1458606338, 
        "expired": true 
       } 
      ] 
     }, 
     { 
      "id": 2, 
      "content": [ 
       { 
        "ts": 1439802083, 
        "value": 430, 
        "meta": "some meta info …" 
       } 
      ] 
     }, 
     { 
      "id": 42, 
      "content": [ 
       { 
        "ts": 1458518979, 
        "value": 518, 
        "meta": "some meta info …" 
       } 
      ] 
     }, 
     { 
      "id": 1337, 
      "content": [ 
       { 
        "ts": 1458633188, 
        "value": 384, 
        "meta": "some meta info …" 
       } 
      ] 
     } 
    ] 
} 
+0

idがドキュメントフィールドの一部ではないスキームを使用すると、アップデートが危険に陥る可能性があります。 現在、私は特定のシリーズにプッシュすることができています: \t db.s.update({_ ID:/ * ... * /}、{ \t \t $プッシュ:{ "series.1337":{ "TS" :123、 "ヴァル":12、 "M": "..."}} \t}) Iをプッシュするための配列インデックスを使用する肝炎であろうあなたの提案方式を使用して: \t db.s.update({ {"series.content":{"ts":123、 "val":12、 "m": "..."}} \t} {id:/ * ... * /}、{ \t \t} ) – PeterPan

+0

これは、ワロンにプッシュすることができます複数の新しいシリーズが同時に作成されたときに、配列を取得することができます。 \t db.s.update({_ ID:/ * ... * /}、{ \t \t $プッシュ:{ "シリーズ":{ \t \t \t "ID":2048、 \t \t \t "コンテンツ": [{ "TS":123、 "ヴァル":12、 "M": "..."}] \t \t}} \t}) しかし、おそらく、このリスクはそれを試してみることにしそうはほとんどありません。 – PeterPan

+0

ネストされたドキュメントに一意のIDがあります。つまり、正しい入れ子になったドキュメントをpushするために、あなたのアップデートで '$'か '$ elemMatch'のどちらかを使うことができます。 – BanksySan

関連する問題