2013-01-12 5 views
20

Ich benutze mongodb + node.js + mongoose.js ORM-Backend.Wie mongodb "Schema" Änderung in der Produktion zu behandeln

Lassen Sie sagen, II haben einige verschachtelte Array von Objekt ohne _id Feld

mongoose.Schema({ 
    nested: [{ 
    _id: false, prop: 'string' 
    }] 
}) 

Und dann habe ich auf alle verschachtelten objectds Ad _id Feld wollen, so der Mungo-Schema

mongoose.Schema({ 
    nested: [{ 
    prop: 'string' 
    }] 
}) 

Dann wäre Ich sollte ein Skript ausführen, um die Produktions-DB zu ändern, oder? Was ist der beste Weg, um mit solchen Veränderungen umzugehen? Mit welchem ​​Tool (oder Ansatz) lässt sich die Änderung am besten umsetzen?

+0

Aus dem Beispiel, das Sie angegeben haben, sieht es so aus, als ob Sie die _id entfernen möchten, anstatt sie hinzuzufügen. Wenn Sie eine _id hinzufügen möchten, wie bestimmen Sie, was jede _id sein sollte? – Eduardo

+0

Ich verstehe dich nicht. _id: false sagt mongoose, keine _id für Objekte zu erzeugen, die durch das Schema beschrieben werden, wenn ich _id: false aus der Schemabeschreibung entferne mongoose erstellt neue Dokumente mit generierten _id. Was ich frage, ist der richtige Weg, alle vorhandenen Objekte (die keine _id haben) mit neuen _ids zu füllen. – WHITECOLOR

+0

sollten die _ids vom System oder von Ihnen generiert werden? – Eduardo

Antwort

12

Einer der wesentlichen Vorteile von schemalosen Datenbanken besteht darin, dass Sie nicht die gesamte Datenbank mit neuen Schemalayouts aktualisieren müssen. Wenn einige der Dokumente in der Datenbank keine bestimmten Informationen enthalten, kann Ihr Code stattdessen die entsprechende Aktion ausführen oder wählen, ob Sie nun mit diesem Datensatz etwas tun möchten.

Eine weitere Option ist faul aktualisieren die Dokumente wie erforderlich - nur wenn sie erneut angeschaut werden. In diesem Fall können Sie sich für ein Flag für die Aufzeichnung pro Dokument/Dokument entscheiden - das anfänglich möglicherweise gar nicht erscheint (und somit eine "Version 0" bedeutet). Aber auch das ist optional. Stattdessen sucht Ihr Datenbankzugriffscode nach Daten, die er benötigt, und wenn er nicht vorhanden ist, weil es sich um neue Informationen handelt, die nach einer Codeaktualisierung hinzugefügt wurden, würde er die Ergebnisse so gut wie möglich ausfüllen.

Für Ihr Beispiel eine _id:false in ein Standard-MongoId Feld umwandelt, wenn der Code (oder zurückgeschrieben nach einem Update) gelesen wird, und die _id:false aktuell eingestellt ist, dann die Änderung machen und schreiben nur, wenn es absolut erforderlich.

+0

Sorry, ich verstehe nicht, was du mit '_id: false' meinst. Ich bin wirklich interessiert. Kannst du es bitte erklären? – hgoebl

+0

Ah, ich habe den Fragetext nicht gelesen, tut mir leid, es ist nicht deine Schuld. Aber das Beispiel mit '_id: false' könnte für die ganze Frage ein wenig irreführend sein. Wäre schön, ein Beispiel zu haben, das für alle besser verständlich ist und besonders für diejenigen, die Mongoose nicht benutzen. – hgoebl

+1

Wie wird dies mit Operationen wie das Hinzufügen eines neuen Index: 'patientSchema.index ({patientId: 1, Institut: 1}, {unique: true})', in Dev musste ich den alten Index ohne '{unique : true} 'damit es funktioniert –

10

Sie müssen in der Tat das Skript schreiben, das über eine Sammlung gehen und jedem Dokument ein neues Feld hinzufügen wird. Wie genau Sie dies tun, hängt jedoch von der Größe Ihrer Datenbank und der Leistung Ihres Speichersystems ab. Das Hinzufügen eines Felds zum Dokument ändert seine Größe und verursacht in den meisten Fällen eine Verlagerung. Diese Operation hat Auswirkungen auf IO und auch darauf beschränkt. Wenn Ihre Sammlung nur ein paar tausend Dokumente ist, kann es bis zu einhunderttausend sein, dann können Sie einfach in einer Schleife darüber iterieren, weil die gesamte Sammlung wahrscheinlich in den Speicher passt und alle IO danach passieren werden. Wenn jedoch die Erfassung weit über den verfügbaren Speicher hinausreicht, ist der Ansatz komplizierter. Wir folgen in der Regel die nächsten Schritte in der Produktion Verwendung von MongoDB:

  • Öffnen Cursor mit Timeout = False
  • Run Update-Abfragen auf diese Dokumente
  • Schlaf für einige Zeit ein Stück von Dokumenten in den Speicher zu vermeiden IO-Subsystem Überlastung und zu verletzen Produktionsanwendung
  • wiederholen, bis
  • Schließen Sie den Cursor done :)

Größe der Dokumente Chunk und Schlafperiode muss experimentell bestimmt werden. Normalerweise möchten Sie QR/QW in Mongostaten für den Zeitraum der Migration vermeiden. Bei größeren Sammlungen auf langsameren Laufwerken (wie EBS bei Amazon) kann dieser IO-sichere Ansatz Stunden bis Tage dauern.

+0

Haben Sie ein Beispiel für einen kurzen Code für den Cursor? Ich bin besonders interessiert an JavaScript-Version, weil ich denke, es ist nicht trivial, vor allem schlafen für einige Zeit und nicht parallel zu bekommen ... – hgoebl

+0

Ich habe kein Beispiel für JavaScript, aber in PyMongo-Treiber deaktivieren Timeout für den Cursor durch einfaches Übergeben timeout = False für die Methode find(). Ich denke, dass JavaScript-Treiber so etwas haben wird. –

Verwandte Themen