2016-06-28 17 views
0

Es gibt viele Artikel und SO-Fragen zum MongoDB-Datenmodell zum Speichern alter Revisionen von Dokumenten.MongoDB-Design für revisionierte Daten

Jedoch fand ich nichts, das eine meiner Anforderungen erfüllte; Ich muss in der Lage sein, die Datenbank rückwirkend abzufragen, um alle Dokumente eindeutig zu finden, die zu einem bestimmten Zeitpunkt ein willkürliches Kriterium erfüllten.

Um zu klären, muss ich in der Lage sein, die Frage effizient zu beantworten;

"Welche Dokumente (und vorzugsweise Versionen) stimmten den Kriterien {X: Y ...} zur Zeit T" zu.

Pseudocode:

/* Would match a version that were active from 2010 - 2016-05-01 with zipcode 12345 */ 
db.my_objs.find({zipcode: "12345", ~time: ISODate("2016-01-01 22:14:31.003")~}) 

Ich habe es nicht geschafft eine Lösung zu finden, die weder auf Google noch ich. Ich habe versucht;

  1. Mit einem einfachen „aus“ auf Daten -timestamp, und wählen Sie dann „das erste Element vor meinem abgefragt Zeitpunkt, die auch andere Kriterien entspricht“, aber ich habe es nicht geschafft, dass in Mongo auszudrücken.
  2. Mit einem von/zu jeder Version, und immer wenn ich eine neue Version schreibe, update "to" auf der vorherigen Version zu entsprechen von der neuen Version. Ich habe jedoch keinen Weg gefunden, dies atomar oder mit einer eventuellen Konsistenz zu tun, was bedeutet, dass mehrere Aktualisierungen Verwüstungen anrichten und mehrdeutige Zeitlinien erzeugen könnten. (Doppeleinträge für den gleichen Zeitpunkt)

Irgendwelche Ideen?

bearbeiten eine unerwünschte Beispiel Abfrage für # 1

db.my_objs.find({ 
    data : { 
     $elemMatch : { 
      from : { 
       $lte : ISODate('2015-01-01') 
      } 
     } 
    } 
}, { 
    "data.$" : 1 
}).forEach(function (obj) { 
        if(obj.data[0].state == 'active') { 
     printjson(registrar) 
    } 
})– 
+0

könnten Sie zeigen Sie Ihre Anfrage nach 'Nummer 1'? – profesor79

+0

Wie ich schrieb, war ich nicht in der Lage, eine solche Abfrage auszudrücken? – Rawler

+0

ok, habe das - dachte, dass du eine Skizze davon hast – profesor79

Antwort

0

Aggregation Rahmen und $unwind Phase, die Array in einzelnes Dokument transformiert, damit wir

Beispiel Dokument anspruchsvollen $match Zustand erstellen

{ 
    "_id" : ObjectId("577275589ea91b3799341aba"), 
    "title" : "Test of design", 
    "firstCreated" : ISODate("2016-06-28T13:02:16.156Z"), 
    "lastUpdated" : ISODate("2016-06-28T13:02:16.156Z"), 
    "firstAuthor" : "profesor79", 
    "lastAuthor" : "Rawler", 
    "versions" : [{ 
      "versionId" : 1.0, 
      "dateCreated" : ISODate("2015-10-10T00:00:00.000Z"), 
      "datePublished" : ISODate("2015-10-12T00:00:00.000Z"), 
      "isActive" : false, 
      "documnetPayload" : { 
       "a" : 1.0, 
       "b" : 2.0, 
       "c" : 3.0 
      } 
     }, { 
      "versionId" : 2.0, 
      "dateCreated" : ISODate("2015-12-10T00:00:00.000Z"), 
      "datePublished" : ISODate("2015-12-31T00:00:00.000Z"), 
      "isActive" : true, 
      "documnetPayload" : { 
       "a" : 1.0, 
       "b" : 3.0, 
       "c" : 30.0 
      } 
     }, { 
      "versionId" : 3.0, 
      "dateCreated" : ISODate("2016-01-31T00:00:00.000Z"), 
      "datePublished" : ISODate("2016-02-21T00:00:00.000Z"), 
      "isActive" : true, 
      "documnetPayload" : { 
       "a" : 11.0, 
       "b" : 3.0, 
       "c" : 31.0 
      } 
     } 
    ] 
} 

Aggregation Rahmen Beispiel

db.rawler.aggregate([{ 
      $match : { 
       "_id" : ObjectId("577275589ea91b3799341aba") 
      } 
     }, { 
      $unwind : "$versions" 
     }, { 
      $match : { 
       $and : [{ 
         "versions.dateCreated" : { 
          $gt : ISODate("2015-10-10T00:00:00.000Z") 
         } 
        }, { 
         "versions.dateCreated" : { 
          $lte : ISODate("2016-01-30T00:00:00.000Z") 
         } 
        } 
       ], 

       "versions.datePublished" : { 
        $gt : new Date("2015-10-13T00:00:00.000") 
       }, 
       // "versions.versionId" :{$in:[1,3,4,5]}, 

      } 
     }, { 
      $sort : { 
       "versions.dateCreated" : -1 
      } 
     }, 

    ]) 
+0

"Verschiebe Datenprozess zur Anwendung", kann mit fast jedem Design durchgeführt werden. (Zum Beispiel in dem Beispiel, das ich Ihnen auf Anfrage gab) Der Wunsch/Wunsch hier war, schnell die Frage zu beantworten "welche Dokumente (und vorzugsweise Versionen) zu einer bestimmten Zeit, hatte das Attribut X auf Y", serverseitig und vorzugsweise zumindest von Indizes unterstützt. Ich sehe nicht, wie das mit diesem vorgeschlagenen Schema funktioniert. Wie würde eine solche Abfrage aussehen? – Rawler

+0

Was ist die Standardgröße eines einzelnen Dokuments? – profesor79

+0

Einzeldokument-Version; 1-2KB. (Bis zu 25 Versionen über die gesamte Lebensdauer) – Rawler