猫鼬:findOneAndUpdate不返回更新的文档


254

下面是我的代码

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

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

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

然后,我再次运行该代码,并修改了结果。

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

Answers:


527

为什么会这样?

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

猫鼬文档

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

可用选项

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

传递{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);
});

15
对于我来说,这似乎很糟,它仍然返回带有新文件的旧文件:true。
PDN

@PDN您拥有什么版本的mongoose / mongo?这可能会弄乱它的工作方式。
科尔·埃里克森

5
对我来说很有意义,因为您已经可以访问新文档了
danday74 '16

3
它对我有用,我使用的是Moogose版本4.6.3,谢谢
cesar andavisa 16-10-20

2
MongoDB中的NodeJS本地使用-{ returnOriginal: false }
尼克Grealy

78

对于使用Node.js驱动程序而不是Mongoose的任何人,您都想使用{returnOriginal:false}而不是{new:true}


1
谢谢!这对我有用mongodb节点版本2.2.27
Kevin Ng

6
这是一种白痴API。为什么不为Mongoose使用与本地API相同的签名?为什么不默认返回更新的文档?猫鼬是我每天都使用的刺激性更强的库之一。
Askdesigners,

56

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

MongoDB外壳

{returnNewDocument: true}

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

猫鼬

{new: true}

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

Node.js MongoDB驱动程序API:

{returnOriginal: false}

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


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

39

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

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

});

2
为什么为_id空?
chovy

14

对于使用原生承诺的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 */ }

15
如果您不提供回调函数,猫鼬将返回一个Promise。无需创建自己的承诺!
joeytwiddle

1
如果您不提供回调,则@joeytwiddle猫鼬不会返回Promise。相反,它返回仅提供Promise API的一小部分的Query对象。这是根据猫鼬的文档。
杰米·里丁

13

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

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


3

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

由官方的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

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

2

下面显示了猫鼬的查询findOneAndUpdate。这new: true是用来获取更新的文档和fields并用于获取特定字段。

例如。 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

我知道,我已经迟到了,但让我在这里添加简单有效的答案

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.