Ci-dessous mon code
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = mongoose.model('Cat', {
name: String,
age: {type: Number, default: 20},
create: {type: Date, default: Date.now}
});
Cat.findOneAndUpdate({age: 17}, {$set:{name:"Naomi"}},function(err, doc){
if(err){
console.log("Something wrong when updating data!");
}
console.log(doc);
});
J'ai déjà quelques enregistrements dans ma base de données mongo et j'aimerais exécuter ce code pour mettre à jour le nom pour lequel l'âge est de 17 ans, puis afficher le résultat à la fin du code.
Cependant, je reçois toujours le même résultat depuis la console (pas le nom modifié) mais quand je vais en ligne de commande mongo db et que je tape "db.cats.find();
". Le résultat est venu avec un nom modifié.
Ensuite, je retourne pour exécuter ce code à nouveau et le résultat est modifié.
Ma question est la suivante: si les données ont été modifiées, alors pourquoi j’ai quand même obtenu les données originales lors de la première utilisation par console.log.
La valeur par défaut consiste à renvoyer le document d'origine non modifié . Si vous souhaitez que le nouveau document mis à jour soit renvoyé, vous devez passer un argument supplémentaire: un objet dont la propriété new
est définie sur true
.
De la documentation sur la mangouste :
Requête # findOneAndUpdate
Model.findOneAndUpdate(conditions, update, options, (error, doc) => { // error: any errors that occurred // doc: the document before updates are applied if `new: false`, or after updates if `new = true` });
Options disponibles
new
: bool - si true , retourne le modifié document plutôt que l'original. La valeur par défaut est false (modifié en 4.0)
Donc, si vous voulez que le résultat mis à jour soit dans la variable doc
:
Cat.findOneAndUpdate({age: 17}, {$set:{name:"Naomi"}}, {new: true}, (err, doc) => {
if (err) {
console.log("Something wrong when updating data!");
}
console.log(doc);
});
Si vous utilisez le pilote Node.js au lieu de Mongoose, vous voudrez utiliser {returnOriginal:false}
au lieu de {new:true}
.
Donc, "findOneAndUpdate" nécessite une option pour retourner le document original. Et, l'option est:
{returnNewDocument: true}
Réf.: https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/
{new: true}
Réf .: http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate
{returnOriginal: false}
Réf.: http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#findOneAndUpdate
Par défaut, findOneAndUpdate renvoie le document d'origine. Si vous voulez qu'il renvoie le document modifié, passez un objet options { new: true }
à la fonction:
Cat.findOneAndUpdate({ age: 17 }, { $set: { name: "Naomi" } }, { new: true }, function(err, doc) {
});
Pour ceux qui découvrent le style ES6/ES7 avec des promesses natives, voici un modèle que vous pouvez adopter ...
const user = { id: 1, name: "Fart Face 3rd"};
const userUpdate = { name: "Pizza Face" };
try {
user = await new Promise( ( resolve, reject ) => {
User.update( { _id: user.id }, userUpdate, { upsert: true, new: true }, ( error, obj ) => {
if( error ) {
console.error( JSON.stringify( error ) );
return reject( error );
}
resolve( obj );
});
})
} catch( error ) { /* set the world on fire */ }
Ceci est le code mis à jour pour findOneAndUpdate
. Ça marche.
db.collection.findOneAndUpdate(
{ age: 17 },
{ $set: { name: "Naomi" } },
{
returnNewDocument: true
}
)
Si vous souhaitez renvoyer le document modifié, vous devez définir l'option {new:true}
référence API, vous pouvez utiliser Cat.findOneAndUpdate(conditions, update, options, callback) // executes
.
Pris par l'API officielle Mongoose http://mongoosejs.com/docs/api.html#findoneandupdate_findOneAndUpdate vous pouvez utiliser les paramètres suivants
A.findOneAndUpdate(conditions, update, options, callback) // executes
A.findOneAndUpdate(conditions, update, options) // returns Query
A.findOneAndUpdate(conditions, update, callback) // executes
A.findOneAndUpdate(conditions, update) // returns Query
A.findOneAndUpdate() // returns Query
Une autre implémentation qui n’est pas exprimée dans la page officielle de l’API et que je préfère utiliser est l’implémentation de base Promise
qui vous permet d’avoir .catch
où vous pouvez gérer toutes vos erreurs diverses.
let cat: catInterface = {
name: "Naomi"
};
Cat.findOneAndUpdate({age:17}, cat,{new: true}).then((data) =>{
if(data === null){
throw new Error('Cat Not Found');
}
res.json({ message: 'Cat updated!' })
console.log("New cat data", data);
}).catch( (error) => {
/*
Deal with all your errors here with your preferred error handle middleware / method
*/
res.status(500).json({ message: 'Some Error!' })
console.log(error);
});
Ci-dessous montre la requête pour findOneAndUpdate
de la mangouste. Ici new: true
est utilisé pour obtenir le document mis à jour et fields
est utilisé pour des champs spécifiques à obtenir.
par exemple. findOneAndUpdate(conditions, update, options, callback)
await User.findOneAndUpdate({
"_id": data.id,
}, { $set: { name: "Amar", designation: "Software Developer" } }, {
new: true,
fields: {
'name': 1,
'designation': 1
}
}).exec();