본문 바로가기
개발 프레임워크/Mongoose, TypeGoose

[Mongoose] strictQuery란? (Strict, Implicit $in)

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

strictQuery, Strict와 차이점, strictQuery 옵션 종류,  Implicit $in

 

strictQuery란?

Mongoose는 쿼리 필터에 대한 strict 모드를 피하기 위해 별도의 strictQuery 옵션을 지원한다.

빈 쿼리 필터로 인해 Mongoose가 모델의 모든 문서를 반환하여 문제가 발생할 수 있기 때문이다.

const mySchema = new Schema({ field: Number }, { strict: true });
const MyModel = mongoose.model('Test', mySchema);

MyModel.find({ notInSchema: 1 });

문제점: Mongoose는 'strict: true' 때문에 'notInSchema: 1'을 필터링합니다. 즉, 이 쿼리는 'tests' 컬렉션의 모든 문서를 반환한다.

 

 

Strict 옵션 vs strictQuery 옵션

Strict 옵션은 업데이트에 적용되고. strictQuery 옵션은 쿼리 필터에만 사용된다.

MyModel.updateMany({}, { $set: { notInSchema: 1 } });

'strict'가 'true'인 경우 Mongoose는 'notInSchema'를 업데이트에서 제거한다.

 

const mySchema = new Schema({ field: Number }, {
  strict: true,
  strictQuery: false
});
const MyModel = mongoose.model('Test', mySchema);
MyModel.find({ notInSchema: 1 });

 strictQuecy: false이므로 Mongoose는 notInSchema:1을 제거하지 않는다

 

 

* 사용자 정의 개체를 쿼리 필터로 전달할 때

일반적으로 사용자 정의 개체를 쿼리 필터로 전달하지 않는 것이 좋다.

// 좋지 않은 방법
const docs = await MyModel.find(req.query);

// 좋은 방법
const docs = await MyModel.find({ name: req.query.name, age: req.query.age }).setOptions({ sanitizeFilter: true });

 

Mongoose 7에서 strictQuery는 기본적으로 false이다. ( 6에서는 true이다 )

그러나 이 동작을 아래와 같이 전역적으로 재정의할 수 있다.

mongoose.set('strictQuery', true);

쿼리에서 알 수 없는 필드를 생략하려면 `strictQuery`를 `true`로 설정해야한다.

 

 

Mongoose에는 필터 매개변수의 엄격 모드를 쿼리로 전환하는 별도의 strictQuery 옵션이 3가지 있다.

strictQuery: false

const mySchema = new Schema({ field: Number }, {
  strict: true,
  strictQuery: false
});
const MyModel = mongoose.model('Test', mySchema);

MyModel.find({ notInSchema: 1 });

 

 

기본적으로 Mongoose는 스키마에 없는 필터 속성을 캐스팅하지 않습니다.

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

'notInSchema'가 스키마에 정의되어 있지 않아도 오류가 없다

 

 

strictQuery: true

mongoose.deleteModel('Character');
const schema = new mongoose.Schema({ name: String, age: Number }, {
  strictQuery: true
});
Character = mongoose.model('Character', schema);

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

await query.exec();
query.getFilter(); // 빈 개체 '{}', 몽구스가 'notInSchema'를 제거함

 

스키마에 대한 strictQuery 옵션을 사용하여 이 동작을 구성할 수 있다.

위에서 설명했다 싶이 이 옵션은 strict 옵션과 유사하다.

strictQuery를 true로 설정하면 필터에서 비스키마 속성이 제거된다.

 

 

strictQuery: "throw"

mongoose.deleteModel('Character');
const schema = new mongoose.Schema({ name: String, age: Number }, {
  strictQuery: 'throw'
});
Character = mongoose.model('Character', schema);

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

const err = await query.exec().then((data) => data, err => err);

필터에 스키마에 없는 속성이 있는 경우 Mongoose에서 오류를 발생시키려면 strictQuery를 'throw'로 설정한다.

 

 

Implicit $in (암시적 $in)

스키마 때문에 Mongoose는 어떤 유형의 필드가 있어야 하는지 알고 있으므로 깔끔한 구문을 제공할 수 있다.

예를 들어 배열이 아닌 필드에 $in을 입력하는 것을 잊은 경우 Mongoose가 $in을 추가한다.

// 보통 name은 문자열이기 때문에 아무것도 찾을 수 없지만 몽구스는 자동으로 '$in'을 삽입한다
const query = Character.findOne({ name: ['Jean-Luc Picard', 'Will Riker'] });

const doc = await query.exec();
doc.name; // "Jean-Luc Picard"

// `{ name: { $in: ['Jean-Luc Picard', 'Will Riker'] } }`
query.getFilter();
반응형

댓글