J’ai le modèle suivant pour les utilisateurs:
var UserSchema = new mongoose.Schema({ name: Ssortingng, dob: Date, sex: Ssortingng, photo: Ssortingng, email: {type: Ssortingng, index: {unique: true, required: true}}, created: {type: Date, default: Date.now} }); var User = mongoose.model('Users', UserSchema);
Comme vous pouvez le constater, le champ “créé” prend une valeur par défaut de la date du jour afin qu’il soit automatiquement défini lors de la création d’un nouvel utilisateur.
J’utilise la requête suivante lorsque les détails de l’utilisateur sont publiés:
User.findOneAndUpdate({email: user.email}, user, {upsert: true}, function (err, user) { if (err) { return callback (err); } else { callback(null, user); } });
L’utilisation de findOneAndUpdate
avec upsert: true
pour objective de renvoyer un profil existant ou d’en créer un nouveau. Il met également à jour les champs en fonction des données publiées.
Toutefois, le champ created
est mis à jour avec la date du jour à chaque fois, même si le champ créé n’est pas enregistré. Comment puis-je m’assurer que ce champ n’est défini qu’une seule fois?
MODIFIER
Un exemple d’object de la firebase database:
{ "_id" : ObjectId("54620b38b431d48bce7cab81"), "email" : "som[email protected]", "__v" : 0, "name" : "somone", "sex" : "male" }
Il s’avère que le champ created
n’est pas défini même lors de la création d’un nouvel object à l’aide de upsert. Mongoose renvoie simplement la date en cours en fonction du schéma même s’il n’existe pas dans le document.
La question devient donc la suivante: comment puis-je m’assurer que l’utilisation de upsert
crée la valeur par défaut pour un champ non fourni dans les arguments?
findOneAndUpdate
envoie simplement une demande MongoDB findAndModify
(voir findOneAndUpdate ). Ce que cela signifie, c’est qu’il omet toute la magie mongoose impliquée dans les configurateurs de schéma, les getters, les valeurs par défaut, etc. La validation n’est exécutée que lors de la création / sauvegarde, il faut donc effectuer un. nouveau, puis .save()
.
voir ce numéro pour plus de discussion
MODIFIER:
En ce qui concerne la première question sur le changement de date à chaque fois, vous pouvez changer un peu le schéma. Supprimez la valeur par défaut et ajoutez-le à la place après avoir déclaré le schéma:
UserSchema.pre("save", function (next) { if (!this.created) { this.created = new Date(); } next(); });
Cela ne créera une date que si la valeur created:
est .save()
et devrait l’empêcher de modifier chaque fois la date de création (lors de l’utilisation de .save()
).
voir le middleware Mongoose
Pour append des valeurs par défaut à votre document s’il avait été créé avec findOneAndUpdate (il n’existait pas avant la requête) et que vous n’avez pas fourni le champ dans la mise à jour, vous devez utiliser setDefaultsOnInsert .
Lorsque upsert et setDefaultsOnInsert ont tous les deux la valeur true, les valeurs par défaut sont définies si l’enregistrement n’est pas trouvé et qu’un nouvel enregistrement est créé. Cela évite au stream de travaux de devoir vérifier si l’enregistrement existe et, dans le cas contraire, d’en créer un nouveau avec «save» pour s’assurer que les valeurs par défaut sont définies.
J’ai eu le même problème (enregistrement créé avec findOneAndUpdate avec upsert: true) et la valeur par défaut d’un champ n’a pas été ajoutée à l’enregistrement, même s’il figurait dans le schéma. Cela concerne uniquement l’ajout de valeurs par défaut lors de l’utilisation de findOneAndUpdate pour créer des documents, et non pour ignorer la mise à jour du champ “créé”.
c’est-à-dire User.findOneAndUpdate ({email: user.email}, utilisateur, {upsert: true, setDefaultsOnInsert: true}, …)