web-dev-qa-db-fra.com

Mongoose Modification du format de schéma

Nous développons rapidement une application utilisant Mongoose et nos schémas changent souvent. Je n'arrive pas à trouver le moyen approprié de mettre à jour un schéma pour des documents existants, sans les supprimer et les recréer complètement à partir de zéro.

Je suis tombé sur http://mongoosejs.com/docs/api.html#schema_Schema-add , qui semble avoir raison. Il existe peu ou pas de documentation sur la manière de mettre en œuvre cela, ce qui rend les choses très difficiles pour quelqu'un qui est nouveau à MongoDB.

Je veux simplement ajouter un nouveau champ appelé activé. Ma définition de schéma est:

var sweepstakesSchema = new Schema({
    client_id: {
        type: Schema.Types.ObjectId,
        ref: 'Client',
        index: true
    },
    name: {
        type: String,
        default: 'Sweepstakes',
    },
    design: {
        images: {
            type: [],
            default: []
        },
        elements: {
            type: [],
            default: []
        }
    },
    enabled: {
        type: Boolean,
        default: false
    },
    schedule: {
        start: {
            type: Date, 
            default: Date.now
        },
        end: {
            type: Date,
            default: Date.now
        }
    },
    submissions: {
        type: Number,
        default: 0
    }
});
23
Nick Parsons

Mongoose ne contient aucun élément concernant la migration de documents existants pour se conformer à un changement de schéma. Vous devez le faire dans votre propre code, si nécessaire. Dans un cas comme le nouveau champ enabled, il est probablement plus simple d'écrire votre code afin qu'il traite un champ enabled manquant comme s'il était défini sur false afin que vous n'ayez pas à toucher aux documents existants.

Dans la mesure où le schéma change lui-même, il vous suffit de mettre à jour votre définition Schema comme vous l'avez montré, mais les modifications telles que les nouveaux champs comportant des valeurs default n'affecteront que les nouveaux documents.

12
JohnnyHK
  db.sweepstakesModel.find( { enabled : { $exists : false } } ).forEach(
   function (doc) {
       doc.enabled = false;
       db.sweepstakesModel.save(doc);
    }
  )

en considérant votre nom de modèle mangouste comme "sweepstakesModel", ce code ajouterait "activé" champ avec la valeur booléenne "false " à tous les documents préexistants de votre collection.

10
Vickar

Je cherchais aussi quelque chose comme une migration, mais je ne l'ai pas trouvée. Comme alternative, vous pouvez utiliser les valeurs par défaut. Si une clé a une valeur par défaut et que la clé n'existe pas, elle utilisera la valeur par défaut.

Mongoose Defaults

Les valeurs par défaut sont appliquées lors de la construction du squelette du document. Cela signifie que si vous créez un nouveau document (nouveau MyModel) ou si vous trouvez un document existant (MyModel.findById), les deux auront des valeurs par défaut à condition qu'une certaine clé soit manquante.

1
blablabla

J'ai eu exactement le même problème et j'ai constaté qu'utiliser findOneAndUpdate() plutôt que d'appeler save nous permettait de mettre à jour le fichier de schéma sans avoir à supprimer tous les anciens documents au préalable.

Je peux poster un extrait de code si demandé.

0
Janac Meena