Firavun Faresi: findOneAndUpdate güncellenmiş dokümanı döndürmüyor


257

Kodum aşağıda

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

Zaten benim mongo veritabanında bazı kayıt var ve ben 17 yaş için adını güncellemek ve daha sonra kod sonunda yazdırmak çıktı için bu kodu çalıştırmak istiyorum.

Ancak, neden hala aynı sonucu (değiştirilmiş adı değil) konsoldan almak ama mongo db komut satırı gidin ve " db.cats.find();" yazın. Sonuç değiştirilmiş adla geldi.

Sonra bu kodu tekrar çalıştırmak için geri dönün ve sonuç değiştirildi.

Sorum şu: Veriler değiştirildiyse, neden hala ilk kez console.log bunu ilk kez veri aldım.

Yanıtlar:


529

Bu neden oluyor?

Varsayılan döndürmektir orijinal, değiştirilmemiş belgeyi. Yeni, güncellenmiş belgenin döndürülmesini istiyorsanız, ek bir bağımsız değişken iletmeniz gerekir: newözelliği ayarlanmış bir nesne true.

Gönderen firavun faresi docs :

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

Mevcut seçenekler

  • new: bool - true ise , değiştirilen belgeyi orijinalden ziyade döndürür . varsayılanı false (4.0 olarak değiştirildi)

Çözüm

Geçiş {new: true}İçinde güncellenmiş bir sonuç istiyorsanız docdeğişkenin:

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

15
Bu benim için kırılmış gibi görünüyor, yine de eski belgeyi new: true ile döndürüyor.
PDN

@PDN Hangi mongoose / mongo sürümüne sahipsiniz? Bu nasıl çalıştığına bağlı olabilir.
Cole Erickson

5
yeni belgeye zaten erişiminiz olduğundan bana mantıklı geliyor
danday74

3
benim için çalıştı, moogose 4.6.3 sürümünü kullanıyorum, teşekkürler
cesar andavisa

2
NodeJs MongoDB Doğal kullanımlar -{ returnOriginal: false }
Nick Grealy

78

Yerine Gelincik ait node.js sürücüsünü kullanan herkes için, kullanmak isteyeceksiniz {returnOriginal:false}yerine {new:true}.


1
Teşekkür ederim! Bu benim için çalışıyor mongodb düğüm sürümü 2.2.27
Kevin Ng

6
Bu bir tür aptal API. Neden Mongoose için yerel API ile aynı imzaları kullanmıyorsunuz? Neden güncellenmiş dokümanı varsayılan olarak iade etmiyorsunuz? Firavun faresi, her gün kullandığım daha rahatsız edici kütüphanelerden biridir.
Askdesigners

56

Bu nedenle, "findOneAndUpdate", orijinal belgeyi döndürmek için bir seçenek gerektirir. Ve seçenek:

MongoDB kabuğu

{returnNewDocument: true}

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

Gelincik

{new: true}

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

Node.js MongoDB Sürücü API'sı:

{returnOriginal: false}

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


Laravel:'returnDocument' => FindOneAndUpdate::RETURN_DOCUMENT_AFTER
Giacomo Alzetta

39

Varsayılan olarak findOneAndUpdate orijinal belgeyi döndürür. Değiştirilmiş belgeyi döndürmesini istiyorsanız { new: true }, işleve bir seçenekler nesnesi iletin:

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

});

2
neden _idboş?
chovy

14

Yerel vaatlerle ES6 / ES7 stilini kullanarak buna rastlayanlar için, burada benimseyebileceğiniz bir model var ...

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 */ }

15
Mongoose, bir geri arama işlevi sağlamazsanız bir söz verecektir. Kendi vaadinizi yaratmanıza gerek yok!
joeytwiddle

1
@joeytwiddle Mongoose , geri arama yapmazsanız bir Söz vermez. Bunun yerine Promise API'sının yalnızca küçük bir alt kümesini sağlayan bir Query nesnesi döndürür. Bu Mongoose belgelerine göre.
Jamie Ridding

13

Bu için güncellenmiş kod findOneAndUpdate. İşe yarıyor.

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


3

Değiştirilen belgeyi iade etmek {new:true}istiyorsanız, kullanabileceğiniz API referansı seçeneğini ayarlamanız gerekirCat.findOneAndUpdate(conditions, update, options, callback) // executes

Resmi Mongoose API'sı tarafından alınan http://mongoosejs.com/docs/api.html#findoneandupdate_findOneAndUpdate aşağıdaki parametreleri kullanabilirsiniz

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

Başka bir uygulama thats resmi API sayfasında ifade edilmez ve kullanmayı tercih ettiğim şey, orada çeşitli hatalarınızla başa çıkabileceğiniz yere Promisesahip olmanızı sağlayan temel uygulamadır .catch.

    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

Aşağıda mongoose için sorgu gösterir findOneAndUpdate. Burada new: truegüncellenmiş dokümanı almak için fieldskullanılır ve belirli alanların alınması için kullanılır.

Örneğin. 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();

1

Biliyorum, zaten geç kaldım ama basit ve çalışan cevabımı buraya ekleyeyim

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.