Mongoose: findOneAndUpdate nie zwraca zaktualizowanego dokumentu

Poniżej mój kod

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

Mam już jakiś rekord w mojej bazie danych mongo i chciałbym uruchomić ten kod, aby zaktualizować nazwę, dla której wiek wynosi 17 lat, a następnie wydrukować wynik na końcu kodu.

Jednakże, dlaczego wciąż otrzymuję ten sam wynik z konsoli (nie zmienioną nazwę), ale kiedy przechodzę do wiersza poleceń Mongo db i wpisuję " db.cats.find();". Wynik został zmieniony.

Potem wracam do uruchomienia tego kodu ponownie i wynik jest modyfikowany.

Mój pytanie brzmi: Jeśli dane zostały zmodyfikowane, to dlaczego nadal mam oryginalne dane za pierwszym razem, gdy konsola.zapisuj.

Author: Al Fahad, 2015-09-27

11 answers

Dlaczego tak się dzieje?

Domyślnym jest zwrócenie oryginalnego, niezmienionego dokumentu. Jeśli chcesz zwrócić nowy, zaktualizowany dokument, musisz przekazać dodatkowy argument: obiekt z właściwością new ustawioną na true.

Z mongoose docs :

Zapytanie # 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`
});

Dostępne opcje

  • new: bool-if true , return the zmodyfikowany dokument zamiast oryginału. domyślnie false (zmieniony w 4.0)

Rozwiązanie

Podaj {new: true} jeśli chcesz mieć zaktualizowany wynik w zmiennej doc:

//                                                         V--- THIS WAS ADDED
Cat.findOneAndUpdate({age: 17}, {$set:{name:"Naomi"}}, {new: true}, (err, doc) => {
    if (err) {
        console.log("Something wrong when updating data!");
    }

    console.log(doc);
});
 591
Author: XCS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-25 23:45:12

Dla każdego, kto korzysta z węzła.sterownik js zamiast mangusty, będziesz chciał użyć {returnOriginal:false} zamiast {new:true}.

 90
Author: Pedro Hoehl Carvalho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 13:52:26

Tak więc "findOneAndUpdate" wymaga opcji zwracania oryginalnego dokumentu. I, opcja jest:

MongoDB shell

{returnNewDocument: true}

Ref: https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/

Mangusta

{new: true}

Ref: http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate

Węzeł.js MongoDB Driver API:

{returnOriginal: false}

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

 68
Author: Tsuneo Yoshioka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 06:06:07

Domyślnie findOneAndUpdate zwraca oryginalny dokument. Jeśli chcesz zwrócić zmodyfikowany dokument, przekaż obiekt options { new: true } do funkcji:

Cat.findOneAndUpdate({ age: 17 }, { $set: { name: "Naomi" } }, { new: true }, function(err, doc) {

});
 41
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-27 18:53:40

Dla tego, kto natknął się na to używając stylu ES6 / ES7 z natywnymi obietnicami, oto wzór, który możesz przyjąć...

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 */ }
 16
Author: Assaf Moldavsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-01 01:21:36

To jest zaktualizowany kod findOneAndUpdate. To działa.

db.collection.findOneAndUpdate(    
  { age: 17 },      
  { $set: { name: "Naomi" } },      
  {
     returnNewDocument: true
  }    
)
 13
Author: Jobin Mathew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-31 17:15:40

Tutaj Opiekun mangusty. Musisz ustawić opcję new na true (lub równoważnie, returnOriginal na false)

await User.findOneAndUpdate(filter, update, { new: true });

// Equivalent
await User.findOneAndUpdate(filter, update, { returnOriginal: false });

Zobacz Mongoose findOneAndUpdate() docs i ten samouczek na temat aktualizacji dokumentów w Mongoose .

 10
Author: vkarpov15,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-09 16:11:51

Jeśli chcesz zwrócić zmieniony dokument, musisz ustawić opcję {new:true} API reference możesz użyć Cat.findOneAndUpdate(conditions, update, options, callback) // executes

Zrobione przez oficjalne API mangusty http://mongoosejs.com/docs/api.html#findoneandupdate_findOneAndUpdate możesz użyć następujących parametrów

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

Kolejna implementacja, która nie jest wyrażona na oficjalnej stronie API i jest tym, czego wolę używać, to Promise podstawowa implementacja, która pozwala na .catch, gdzie możesz poradzić sobie ze wszystkimi swoimi różne błędy tam.

    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);
    });
 5
Author: Jonathan Thurft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-01 10:04:22

Poniżej znajduje się zapytanie dla mangusty findOneAndUpdate. Tutaj new: true jest używany do uzyskania zaktualizowanego dokumentu, a fields jest używany do uzyskania określonych pól.

Np. 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();
 3
Author: Sourabh Khurana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-05 07:31:04

Wiem, jestem już spóźniony, ale dodam swoją prostą i działającą odpowiedź tutaj

const query = {} //your query here
const update = {} //your update in json here
const option = {new: true} //will return updated document

const user = await User.findOneAndUpdate(query , update, option)
 1
Author: Aljohn Yamaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-05 09:53:10

W niektórych scenariuszach {[1] } nie działa. Więc możesz spróbować tego.

{'returnNewDocument':true}
 1
Author: Prakash Harvani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-13 12:04:17