クエリカスティング
Model.find()
、Query#find()
、Model.findOne()
などへの最初のパラメータはfilter
と呼ばれます。古いコンテンツでは、このパラメータをquery
またはconditions
と呼ぶことがあります。例:
const query = Character.find({ name: 'Jean-Luc Picard' });
query.getFilter(); // `{ name: 'Jean-Luc Picard' }`
// Subsequent chained calls merge new properties into the filter
query.find({ age: { $gt: 50 } });
query.getFilter(); // `{ name: 'Jean-Luc Picard', age: { $gt: 50 } }`
Query#exec()
またはQuery#then()
を使用してクエリを実行すると、モングースはスキーマに一致するようにフィルターをキャストします。
// Note that `_id` and `age` are strings. Mongoose will cast `_id` to
// a MongoDB ObjectId and `age.$gt` to a number.
const query = Character.findOne({
_id: '5cdc267dd56b5662b7b7cc0c',
age: { $gt: '50' }
});
// `{ _id: '5cdc267dd56b5662b7b7cc0c', age: { $gt: '50' } }`
// Query hasn't been executed yet, so Mongoose hasn't casted the filter.
query.getFilter();
const doc = await query.exec();
doc.name; // "Jean-Luc Picard"
// Mongoose casted the filter, so `_id` became an ObjectId and `age.$gt`
// became a number.
query.getFilter()._id instanceof mongoose.Types.ObjectId; // true
typeof query.getFilter().age.$gt === 'number'; // true
モングースがフィルターをスキーマにキャストできない場合、クエリはCastError
をスローします。
const query = Character.findOne({ age: { $lt: 'not a number' } });
const err = await query.exec().then(() => null, err => err);
err instanceof mongoose.CastError; // true
// Cast to number failed for value "not a number" at path "age" for
// model "Character"
err.message;
strictQuery
オプション
既定では、モングースはスキーマにないフィルタープロパティをキャストしません。
const query = Character.findOne({ notInSchema: { $lt: 'not a number' } });
// No error because `notInSchema` is not defined in the schema
await query.exec();
スキーマのstrictQuery
オプションを使用して、この動作を構成できます。このオプションはstrict
オプションに類似しています。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(); // Empty object `{}`, Mongoose removes `notInSchema`
filter
にスキーマにないプロパティがある場合にモングースにエラーをスローさせるには、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(() => null, err => err);
err.name; // 'StrictModeError'
// Path "notInSchema" is not in schema and strictQuery is 'throw'.
err.message;
暗黙的な$in
スキーマにより、モングースはフィールドの型を認識するため、対応した簡潔な構文を提供できます。たとえば、配列以外のフィールドに$in
を付けるのを忘れた場合、モングースが$in
を代わりに入れます。
// Normally wouldn't find anything because `name` is a string, but
// Mongoose automatically inserts `$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();