web-dev-qa-db-fra.com

Mongoose: findOneAndUpdate ne renvoie pas le document mis à jour

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.

215
Dreams

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);
});
444
Cristy

Si vous utilisez le pilote Node.js au lieu de Mongoose, vous voudrez utiliser {returnOriginal:false} au lieu de {new:true}.

57

Donc, "findOneAndUpdate" nécessite une option pour retourner le document original. Et, l'option est:

MongoDB Shell

{returnNewDocument: true}

Réf.: https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/

Mangouste

{new: true}

Réf .: http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate

API du pilote MongoDB Node.js:

{returnOriginal: false}

Réf.: http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#findOneAndUpdate

41
Tsuneo Yoshioka

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) {

});
38
Nishant Shreshth

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 */ }
12
Assaf Moldavsky

Ceci est le code mis à jour pour findOneAndUpdate. Ça marche.

db.collection.findOneAndUpdate(    
  { age: 17 },      
  { $set: { name: "Naomi" } },      
  {
     returnNewDocument: true
  }    
)
9
Jobin Mathew

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);
    });
2
Jonathan Thurft

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();
0
Sourabh Khurana