본문 바로가기
데이터베이스/MongoDB

[Mongoose] Query Casting

by minhyeok.lee 2023. 3. 2.
반응형

Query Casting: Model.find(), Query.prototype.find(), Model.findOne(), Query.prototype.findOne()

Model.find(), Query.prototype.find(), Model.findOne(), Query.prototype.findOne() 등의 첫 번째 매개변수를 filter(필터)라고 한고 이 매개변수는 쿼리 또는 조건이라고도 한다.

 

예시코드)

const query = Character.find({ name: '홍길동' });
query.getFilter(); // `{ name: '홍길동' }`

// 후속 연결 호출은 새 속성을 필터에 병합한다.
query.find({ age: { $gt: 50 } });
query.getFilter(); // `{ name: '홍길동', age: { $gt: 50 } }`

 

query.prototype.exec() 또는 query.prototype.then()을 사용하여 쿼리를 실행하면 Mongoose는 스키마와 일치하도록 필터를 캐스팅한다.

// _id와 age는 문자열, 몽구스는 '_id'를 몽고 DB ObjectId에, 'age.$gt'를 숫자에 캐스팅한다.
const query = Character.findOne({
  _id: '63fd6d2b5702c1bfcd8ab20d',
  age: { $lt: '50' }
});


console.log('첫 번째 쿼리: ', query.getFilter());

const doc = await query.exec();

console.log('두 번째 쿼리: ', query.getFilter());

 

출력값

첫 번째 쿼리: { _id: '63fd6d2b5702c1bfcd8ab20d', age: { '$gt': 50 } }
두 번째 쿼리: { _id: new ObjectId("63fd6d2b5702c1bfcd8ab20d"), age: { '$gt': 50 } }

첫 번째 쿼리: 쿼리가 아직 실행되지 않아서 Mongoose가 필터를 캐스팅하지 않았다.
두 번째 쿼리:  몽구스가 필터를 캐스팅했기 때문에 '_id'는 ObjectId가 되고 'age.$gt'는 숫자가 되었다.

 

 

Mongoose가 필터를 스키마로 캐스팅하지 못하면 쿼리에서 CastError가 발생한다.

const query = Character.findOne({ age: { $lt: 'not a number' } });

const character = await query.exec().then(
  () => null,
  (err) => console.log(err.message),
);

 

출력값

Cast to Number failed for value "not a number" (type string) at path "age" for model "Character"

 

모델 "Character"에 대한 경로 "age"에서 "not a number" 값에 대해 숫자로 캐스팅하지 못하고 Cast 에러가 발생한다.

 

Cast Error 다른 예)

_id의 형태로 바꿀 수 없는 형태로 _id를 보냈을 경우 (_id양식과 다를경우 _ 자릿수 등)

number의 형태로 바꿀 수 없는 형태로 number를 보냈을 경우 (한글, 영어 등)

 

 

반응형

댓글