Door dit tegen te komen en redelijk te begrijpen hoe migraties werken op een relationele database, maakt MongoDB dit een beetje eenvoudiger. Ik ben tot 2 manieren gekomen om dit te doorbreken. De dingen waarmee u rekening moet houden bij het omgaan met gegevensmigraties in MongoDB (niet zo ongewoon voor RDB's) zijn:
- Ervoor zorgen dat lokale testomgevingen niet kapot gaan wanneer een ontwikkelaar het laatste nieuws uit de projectrepository samenvoegt
- Ervoor zorgen dat alle gegevens correct worden bijgewerkt in de live-versie, ongeacht of een gebruiker is aangemeld of uitgelogd als authenticatie wordt gebruikt. (Als iedereen automatisch wordt uitgelogd wanneer een upgrade wordt uitgevoerd, hoeft u zich natuurlijk alleen maar zorgen te maken wanneer een gebruiker inlogt).
1) Als uw wijziging ervoor zorgt dat iedereen uitlogt of er een downtime van de applicatie wordt verwacht, is de eenvoudige manier om dit te doen een migratiescript om verbinding te maken met lokale of live MongoDB en de juiste gegevens te upgraden. Voorbeeld waarbij de naam van een gebruiker wordt gewijzigd van een enkele tekenreeks in een object met een voor- en achternaam (heel eenvoudig natuurlijk en zou in een script moeten worden opgenomen dat door alle ontwikkelaars kan worden uitgevoerd):
De CLI gebruiken:
mongod
use myDatabase
db.myUsers.find().forEach( function(user){
var curName = user.name.split(' '); //need some more checks..
user.name = {given: curName[0], family: curName[1]};
db.myUsers.save( user );
})
2) U wilt dat de toepassing de schema's op en neer migreert op basis van de toepassingsversie die ze gebruiken. Dit zal uiteraard minder belastend zijn voor een live server en er is geen uitvaltijd nodig omdat gebruikers alleen geüpgraded worden wanneer ze de geüpgrade/gedowngradede versies voor de eerste keer gebruiken.
Als u middleware gebruikt in Expressjs voor Nodejs:
- Stel een app-variabele in uw root-app-script in via
app.set('schemaVersion', 1)
die later zal worden gebruikt om te vergelijken met de versie van het gebruikersschema. - Zorg er nu voor dat alle gebruikersschema's ook een eigenschap schemaVersion hebben, zodat we een wijziging kunnen detecteren tussen de versie van het applicatieschema en de huidige MongoDB-schema's, alleen voor DIE BEPAALDE GEBRUIKER.
-
Vervolgens moeten we eenvoudige middleware maken om de configuratie- en gebruikersversie te detecteren
app.use( function( req, res, next ){ //If were not on an authenticated route if( ! req.user ){ next(); return; } //retrieving the user info will be server dependent if( req.user.schemaVersion === app.get('schemaVersion')){ next(); return; } //handle upgrade if user version is less than app version //handle downgrade if user version is greater than app version //save the user version to your session / auth token / MongoDB where necessary })
Voor de upgrade / downgrade zou ik eenvoudige js-bestanden maken onder een migratiemap met een upgrade / downgrade-exportfunctie die het gebruikersmodel accepteert en de migratiewijzigingen op die specifieke gebruiker in de MongoDB uitvoert. Zorg er ten slotte voor dat de gebruikersversie is bijgewerkt in uw MongoDB, zodat ze de wijzigingen niet opnieuw uitvoeren, tenzij ze opnieuw naar een andere versie gaan.