2016-04-08 2 views
2

Ich verwende MongoDB zum Speichern von Zeitreihendaten mit Lücken. Jedes Dokument gehört zu einer Position und enthält die Änderungen für mehrere Messpunkte. Jeder Messpunkt hat eine ID, ich habe im folgenden Beispiel das folgende ID-Schema some-id-XXX verwendet.MongoDB Project/Aggregate, um alle Subdokumente zu erhalten neueste Array-Einträge

Die Anwendung schreibt nur Änderungen in das spezifische Unterdokument. Daher besteht die Möglichkeit von Lücken in der Reihe, in der die APP das gesamte Dokument lädt, prüft sie auf Änderungen und aktualisiert das/die Unterdokument (e) ("some-id-1" zum Beispiel), das Änderungen aufweist.

{ 
    "_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 …" 
      } 
     ] 
    } 
} 

Das Problem bei diesem approcach ist der Verkehr durch das Laden ganzes Dokuments erzeugt, die für die Überprüfung für Änderungen oder Lücken erforderlich ist.

Wenn ich nur den letzten Wert (den letzten Wert im Array) abrufen könnte, würde der Verkehr aufgeschlüsselt werden.

Solange ich die ID kenne, kann ich eine Projektion verwenden, um den letzten letzten Eintrag abzurufen.

Aber da eine Änderung Lücken enthalten kann, kenne ich nicht alle IDs in der Zielserie Dokument.

Gibt es eine Möglichkeit, dies mit dem Aggregation Framework oder mit einer cleveren Projektion zu archivieren?

Meine einzige Idee ist die Speicherung der letzten Werte in einer kompakteren Form und Projekt nur {last_recent: 1}:

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

Aber ich hoffe, dass es eine elegantere Lösung für dieses Problem ist.

+0

Wenn Sie den '„some-id-x“erwarten' Teil als „dynamisch“, dann ist das einfach nicht mit dem Aggregations Rahmen passieren. Es ist auch nicht ein sehr gutes Design, sowohl in der Verwendung von "benannten Schlüsseln" als auch nicht sehr praktisch, um dies für die Speicherung von mehreren Werten auf diese Weise zu verwenden. Dies könnte wirklich mit einem Redesign, da die gesamte Struktur sieht nicht wie eine gute Idee für die beabsichtigte Verwendung, die ich sehen kann. –

Antwort

0

Das Kernproblem ist, dass Sie Daten in den Feldnamen speichern, die die ID sind.

Das Schema sollte wohl sein:

{ 
    "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

Wenn ich ein Schema verwenden würde, wo die ID nicht Teil eines Dokumentfeldes ist, könnten Updates gefährlich werden. Derzeit bin ich auf eine bestimmte Reihe schieben können: \t db.s.update ({_ id:/* ... * /}, { \t \t $ Push: { "series.1337": { "ts" \t db.s.update ({: 123, "val": 12 "m": ich würde hav den Array-Index für Schübe verwenden "..."}} \t}) Wenn Ihr vorgeschlagene Schema mit _id:/* ... * /}, { \t \t $ push: {"series.0.content": {"ts": 123, "val": 12, "m": "..."}} \t}) – PeterPan

+0

Dies könnte dazu führen, dass die Wron drängt g Array, wenn mehrere neue Serien gleichzeitig mit einigen Pushs zu bereits bekannten Serien erstellt werden. \t db.s.update ({_ id:/* ... * /}, { \t \t $ Push: { "Serie": { \t \t \t "id": 2048, \t \t \t "content": [{ "ts": 123, "val": 12 "m": "..."}] \t \t}} \t}) Aber vielleicht ist dieses Risiko so unwahrscheinlich, dass es einen Versuch geben. – PeterPan

+0

Sie haben eine eindeutige ID im geschachtelten Dokument. Dies bedeutet, dass Sie in Ihrem Update entweder $ oder $ elemMatch verwenden können, um das korrekte verschachtelte Dokument zu übertragen. – BanksySan

Verwandte Themen