mongoose의 query 사용 시, callback과 promise를 동시에 쓰면 두번 실행됨
.then()
함수를 가짐 (for co and async/await as a convenience)∴
await 를 쓰려면 await Model.findOneAndUpdate( query, doc, options )
를 쓰거나
await를 지우고 Model.findOneAndUpdate( query, doc, optiosn, callback)
을 쓴다.
mongoose 로 db update 중에 에러를 만났다.
오늘의 년월일 구하기
-> 해당 년월일에 해당하는 document의 count++ 해주기
나의 잘못은 mongoose document에 아주 명확하게 써있었다.
(그래서 교훈은 항상 document 읽는 것을 게을리 하지 말자이다.)
export const updateVisitorCount = async (req, res) => {
let today = getYearMonthDate();
console.log(new Date());
await Visitor.findOneAndUpdate(
{ date: today },
{ $inc: { count: 1 } },
{ new: true, upsert: true },
(err, visitor) => {
if (err) {
console.log(`Something wrong when updating data : ${err}`);
return res.status(500).json(err);
}
return res.status(200).json(visitor);
}
);
};
{ $inc: { count: 1 } }
를 통해서 count가 한번만 증가할 줄 알았는데
Postman으로 테스트 해보니 2씩 증가했다
mongoose.set('debug', true)
를 통해 다음과 같은 결과를 확인했다.
findOneAndUpdate
에
await
가 있을 땐 2번씩 로그가 찍히고 await
가 없을 땐 정상적으로 한번씩 업데이트가 된다.나와 같은 에러를 겪는 사람이 있었고 코멘트는 다음과 같았다.. mongoose guide를 읽어보라고.
참고 : 깃헙이슈
Using a callback and a promise simultaneously will result in the query being executed twice. You should be using one or the other, but not both. Check out the mongoose guide here
그래서 미뤄뒀던 Mongoosejs Queries 가이드를 찬찬히 읽어봤습니다.
Query obj
를 return 함Model.find()
, Model.findOneAndUpdate()
...callback
function Promise
로도 사용 가능.then()
function 도 가지고 있음callback
으로 쿼리를 실행시키면, 쿼리는 JSON document로 specify됨.callback(error, result)
const Visitor = mongoose.model('Visitor', visitorSchema);
Visitor.findOne({'regDate': '210329'}, 'regDate count', (err, visitor) => {
if (err) return handlerError(err);
console.log(`${visitor.regDate} : ${visitor.count}`);
});
query
자료형의 변수가 됨const query = Visitor.findOne({'regDate': '210329'});
query.select('egDate count`);
//execute the query at a later time
query.exec( (err, visitor) => {
if (err) return handlerErr(err);
console.log(`${visitor.regDate} : ${visitor.count}`);
});
Person.
find({ occupation: /host/ }).
where('name.last').equals('Ghost').
where('age').gt(17).lt(66).
where('likes').in(['vaporizing', 'talking']).
limit(10).
sort('-occupation').
select('name occupation').
exec(callback);
.then()
함수를 가짐 (for co and async/await as a convenience)const query = SomeModel.updateMany({}, {isDeleted: true}, function() {
console.log('Update 1');
});
q.then(() => console.log('Update 2'));
q.then(() => console.log('Update 3'));
callback과 promise를 쿼리에 함께 쓰면 두번씩 실행되는 결과를 갖게 됨
(Don't mix using callbacks and promises with queries, or you may end up with duplicate operations)
await와 쿼리에 callback이 있으면 query가 즉각적으로 실행되게 되고, 그러면 바로 then() 함수가 실행되어서 한번 더 실행되게 됩니다.
const someftn = async (req, res) => {
await SomeModel.findOneAndUpdate(
{name: 'sth'},
{value: 'will be changed'},
(err, someModel) => { console.log(err, someModel) }
);
}