Mongoose:findOneAndUpdate不返回更新的文档

Dre*_*ams 229 mongoose mongodb node.js

以下是我的代码

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);
});
Run Code Online (Sandbox Code Playgroud)

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

但是,为什么我仍然从控制台获得相同的结果(不是修改后的名称),但是当我转到mongo db命令行并输入" db.cats.find();"时.结果来自修改后的名称.

然后我回去再次运行此代码并修改结果.

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

Cri*_*sty 469

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

来自mongoose docs:

查询#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`
});
Run Code Online (Sandbox Code Playgroud)

可用选项

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

因此,如果您想要doc变量中的更新结果:

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

    console.log(doc);
});
Run Code Online (Sandbox Code Playgroud)

  • 这似乎对我来说是破碎的,它仍然返回旧文档new:true. (12认同)
  • NodeJs MongoDB Native 使用 - `{ returnOriginal: false }` (6认同)
  • 因为您已经可以访问新文档,所以对我有意义 (5认同)
  • 它对我有用,我使用的是Moogose版本4.6.3,谢谢 (2认同)

Ped*_*lho 61

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

  • 这是一种愚蠢的API。为什么不对 Mongoose 使用与原生 API 相同的签名?为什么不默认返回更新的文档?Mongoose 是我每天使用的比较烦人的库之一。 (14认同)
  • 我正在使用 `"mongodb": "^3.6.9"` 并且 `{ returnOriginal:false }` 已弃用。使用 `{ returnDocument: 'after' }` 代替。 (8认同)
  • 谢谢!这对我有用 mongodb 节点版本 2.2.27 (2认同)

Tsu*_*oka 45

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

MongoDB shell

{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


Nis*_*hth 39

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

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

});
Run Code Online (Sandbox Code Playgroud)

  • 为什么_id为null? (2认同)

vka*_*v15 13

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

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

// Equivalent
await User.findOneAndUpdate(filter, update, { returnOriginal: false });
Run Code Online (Sandbox Code Playgroud)

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


Ass*_*sky 12

对于那些使用本机承诺的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 */ }
Run Code Online (Sandbox Code Playgroud)

  • 如果您不提供回调函数,Mongoose将返回一个承诺.没有必要创建自己的承诺! (15认同)
  • 如果您不提供回调,@joeytwiddle Mongoose ** 不会** 返回 Promise。相反,它返回一个 Query 对象,该对象仅提供 Promise API 的一小部分。这是根据猫鼬文档。 (2认同)

小智 9

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

db.collection.findOneAndUpdate(    
  { age: 17 },      
  { $set: { name: "Naomi" } },      
  {
     returnNewDocument: true
  }    
)
Run Code Online (Sandbox Code Playgroud)


Alj*_*aro 6

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

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)
Run Code Online (Sandbox Code Playgroud)


Jon*_*rft 5

如果要返回更改的文档,则需要设置{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
Run Code Online (Sandbox Code Playgroud)

官方 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);
    });
Run Code Online (Sandbox Code Playgroud)