node.js Mongoose:findOneAndUpdate 不返回更新的文档

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32811510/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 19:20:06  来源:igfitidea点击:

Mongoose: findOneAndUpdate doesn't return updated document

node.jsmongodbmongoose

提问by Dreams

Below is my 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);
});

I already have some record in my mongo database and I would like to run this code to update name for which age is 17 and then print result out in the end of code.

我的 mongo 数据库中已经有一些记录,我想运行此代码来更新年龄为 17 岁的名称,然后在代码末尾打印结果。

However, why I still get same result from console(not the modified name) but when I go to mongo db command line and type "db.cats.find();". The result came with modified name.

但是,为什么我仍然从控制台得到相同的结果(不是修改后的名称),但是当我转到 mongo db 命令行并键入“ db.cats.find();”时。结果带有修改后的名称。

Then I go back to run this code again and the result is modified.

然后我回去再次运行这段代码并修改了结果。

My question is: If the data was modified, then why I still got original data at first time when console.log it.

我的问题是:如果数据被修改了,那为什么我第一次在console.log的时候还是得到原始数据呢?

回答by XCS

Why this happens?

为什么会发生这种情况?

The defaultis to return the original, unaltereddocument. If you want the new, updated document to be returned you have to pass an additional argument: an object with the newproperty set to true.

默认情况下是返回原来的,不变的文件。如果您希望返回新的、更新的文档,您必须传递一个额外的参数:一个new属性设置为的对象true

From the mongoose docs:

猫鼬文档

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

Available options

  • new: bool - if true, return the modifieddocument rather than the original. defaults to false(changed in 4.0)

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

可用选项

  • new: bool - 如果为true,则返回修改后的文档而不是原始文档。默认为 false(在 4.0 中更改)

Solution

解决方案

Pass {new: true}if you want the updated result in the docvariable:

传递{new: true}如果你想更新的结果的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);
});

回答by Pedro Hoehl Carvalho

For anyone using the Node.js driver instead of Mongoose, you'll want to use {returnOriginal:false}instead of {new:true}.

对于使用Node.js的驱动程序,而不是猫鼬的人,你要使用{returnOriginal:false}的替代{new:true}

回答by Tsuneo Yoshioka

So, "findOneAndUpdate" requires an option to return original document. And, the option is:

因此,“findOneAndUpdate”需要一个选项来返回原始文档。而且,选项是:

MongoDB shell

MongoDB 外壳

{returnNewDocument: true}

{returnNewDocument: true}

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

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

Mongoose

猫鼬

{new: true}

{new: true}

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

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

Node.js MongoDB Driver API:

Node.js MongoDB 驱动程序 API:

{returnOriginal: false}

{returnOriginal: false}

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

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

回答by hthserhs

By default findOneAndUpdatereturns the original document. If you want it to return the modified document pass an options object { new: true }to the function:

默认情况下findOneAndUpdate返回原始文档。如果您希望它返回修改后的文档{ new: true },则将选项对象传递给该函数:

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

});

回答by Assaf Moldavsky

For whoever stumbled across this using ES6 / ES7 style with native promises, here is a pattern you can adopt...

对于使用带有原生 promise 的 ES6 / ES7 样式偶然发现此问题的人,这里有一个您可以采用的模式......

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

回答by Jobin Mathew

This is the updated code for findOneAndUpdate. It works.

这是 的更新代码findOneAndUpdate。有用。

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

回答by vkarpov15

Mongoose maintainer here. You need to set the newoption to true(or, equivalently, returnOriginalto false)

猫鼬维护者在这里。您需要将该new选项设置为true(或等效地设置returnOriginalfalse

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

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

See Mongoose findOneAndUpdate()docsand this tutorial on updating documents in Mongoose.

请参阅MongoosefindOneAndUpdate()文档有关在 Mongoose 中更新文档的教程

回答by Jonathan Thurft

If you want to return the altered document you need to set the option {new:true}API reference you can use Cat.findOneAndUpdate(conditions, update, options, callback) // executes

如果要返回更改的文档,则需要设置{new:true}可以使用的选项API 参考Cat.findOneAndUpdate(conditions, update, options, callback) // executes

Taken by the official Mongoose API http://mongoosejs.com/docs/api.html#findoneandupdate_findOneAndUpdateyou can use the following parameters

由官方 Mongoose API http://mongoosejs.com/docs/api.html#findoneandupdate_findOneAndUpdate采取,您可以使用以下参数

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

Another implementation thats is not expressed in the official API page and is what I prefer to use is the Promisebase implementation that allow you to have .catchwhere you can deal with all your various error there.

官方 API 页面中没有表达的另一个实现是我更喜欢使用的Promise基本实现,它允许您在.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);
    });

回答by Sourabh Khurana

Below shows the query for mongoose's findOneAndUpdate. Here new: trueis used to get the updated doc and fieldsis used for specific fields to get.

下面显示了对 mongoose 的findOneAndUpdate. 这里new: true用于获取更新的doc,fields用于特定字段获取。

eg. findOneAndUpdate(conditions, update, options, callback)

例如。 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();