몽구스 : findOneAndUpdate가 업데이트 된 문서를 반환하지 않습니다


256

아래는 내 코드입니다

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

내 몽고 데이터베이스에 이미 레코드가 있으며이 코드를 실행하여 나이가 17 세인 이름을 업데이트 한 다음 코드 끝에 결과를 인쇄하고 싶습니다.

그러나 왜 여전히 콘솔에서 수정 된 이름이 아닌 동일한 결과를 얻지 만 mongo db 명령 줄로 이동하여 " db.cats.find();"를 입력하십시오 . 결과 이름이 수정되었습니다.

그런 다음이 코드를 다시 실행하여 결과가 수정됩니다.

내 질문은 : 데이터가 수정 된 경우 왜 console.log에 처음으로 원래 데이터를 얻었는지입니다.

답변:


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
이것은 나에게 깨진 것처럼 보이며 여전히 오래된 문서를 new : true로 반환합니다.
PDN

@PDN 어떤 몽구스 / 몽고 버전이 있습니까? 작동 방식에 문제가있을 수 있습니다.
Cole Erickson

5
이미 새 문서에 액세스 할 수 있기 때문에 이해가됩니다
danday74

3
그것은, 내가 moogose 버전 4.6.3, 감사를 사용하고 나를 위해 일한
세자르 andavisa

2
NodeJs MongoDB를 네이티브 사용 -{ returnOriginal: false }
닉 Grealy에게

78

Mongoose 대신 Node.js 드라이버를 사용 {returnOriginal:false}하는 사람은 대신 을 사용하고 싶을 것입니다 {new:true}.


1
감사합니다! 이것은 나를 위해 작동합니다 mongodb 노드 버전 2.2.27
Kevin Ng

6
이것은 일종의 바보 API입니다. 몽구스에 네이티브 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 }를 함수에 전달 하십시오.

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

});

2
_idnull입니까?
chovy 2012 년

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
콜백 함수를 제공하지 않으면 몽구스는 약속을 반환합니다. 자신의 약속을 만들 필요가 없습니다!
joeytwiddle

1
콜백을 제공하지 않으면 @joeytwiddle Mongoose 약속을 반환하지 않습니다. 대신 Promise API의 작은 하위 집합 만 제공하는 Query 개체를 반환합니다. 이것은 몽구스 문서에 따른 것입니다.
Jamie Ridding

13

에 대한 업데이트 된 코드입니다 findOneAndUpdate. 효과가있다.

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

9

몽구스 관리자입니다. 당신은 설정해야 new하는 옵션을 true(동등, 또는 returnOriginal으로 false)

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

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

Mongoose findOneAndUpdate()문서Mongoose의 문서 업데이트에 대한이 학습서를 참조하십시오 .


새로운 것이 아니라 returnNewDocument를 작성하는 데 실수를했습니다. 도와 줘서 고마워!
user1111527

3

변경된 문서를 반환하려면 옵션 {new:true}API 참조 를 설정해야 합니다.Cat.findOneAndUpdate(conditions, update, options, callback) // executes

공식 몽구스 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

아래는 mongoose 's에 대한 쿼리를 보여줍니다 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.