when I do
const currencyFound = await Currency.findOne({some_field_that_does_not_exist_in_any_currency : value});
currencyFound is never null, when it logically should be? It seems to be some random document fetched from the Currencies collection, even though none of the documents in the collection, including the one fetched, have a field same as the one specified in the filter for findOne (some_field_that_does_not_exist_in_any_currency).
Similar behaviour when I do
const currenciesFound = await Currency.find({some_field_that_does_not_exist_in_any_currency : value});
I expect an empty list, but I get ALL the records on the collection! What's going on?
UPDATE 1
if I remove await and console.log
the result, this is what I get:
Query {
_mongooseOptions: {},
_transforms: [],
_hooks: Kareem { _pres: Map(0) {}, _posts: Map(0) {} },
_executionStack: null,
mongooseCollection: Collection {
collection: Collection { s: [Object] },
Promise: [Function: Promise],
modelName: 'Currency',
_closed: false,
opts: {
autoIndex: true,
autoCreate: true,
schemaUserProvidedOptions: [Object],
capped: false,
Promise: [Function: Promise],
'$wasForceClosed': undefined
},
name: 'currencies',
collectionName: 'currencies',
conn: NativeConnection {
base: [Mongoose],
collections: [Object],
models: [Object],
config: {},
replica: false,
options: null,
otherDbs: [],
relatedDbs: {},
states: [Object: null prototype],
_readyState: 1,
_closeCalled: undefined,
_hasOpened: true,
plugins: [],
id: 0,
_queue: [],
_listening: false,
_connectionString: 'mongodb://****:****/****',
_connectionOptions: [Object],
client: [MongoClient],
'$initialConnection': [Promise],
db: [Db],
host: '****',
port: ****,
name: '****'
},
queue: [],
buffer: false,
emitter: EventEmitter {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
[Symbol(kCapture)]: false
}
},
model: Model { Currency },
schema: Schema {
obj: { name: [Object], symbol: [Object] },
paths: {
name: [SchemaString],
symbol: [SchemaString],
_id: [ObjectId],
updatedAt: [SchemaDate],
createdAt: [SchemaDate],
__v: [SchemaNumber]
},
aliases: {},
subpaths: {},
virtuals: { id: [VirtualType] },
singleNestedPaths: {},
nested: {},
inherits: {},
callQueue: [],
_indexes: [],
methods: { initializeTimestamps: [Function (anonymous)] },
methodOptions: {},
statics: {},
tree: {
name: [Object],
symbol: [Object],
_id: [Object],
updatedAt: [Function: Date],
createdAt: [Object],
__v: [Function: Number],
id: [VirtualType]
},
query: {},
childSchemas: [],
plugins: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
'$id': 2,
mapPaths: [],
s: { hooks: [Kareem] },
_userProvidedOptions: { timestamps: true },
options: {
timestamps: true,
typeKey: 'type',
id: true,
_id: true,
validateBeforeSave: true,
read: null,
shardKey: null,
discriminatorKey: '__t',
autoIndex: null,
minimize: true,
optimisticConcurrency: false,
versionKey: '__v',
capped: false,
bufferCommands: true,
strictQuery: true,
strict: true,
pluralization: true
},
'$timestamps': { createdAt: 'createdAt', updatedAt: 'updatedAt' },
'$globalPluginsApplied': true,
_requiredpaths: [ 'symbol', 'name' ]
},
op: 'findOne',
options: {},
_conditions: { some_field_that_does_not_exist_in_any_currency: 'GBP' },
_fields: undefined,
_update: undefined,
_path: undefined,
_distinct: undefined,
_collection: NodeCollection {
collection: Collection {
collection: [Collection],
Promise: [Function: Promise],
modelName: 'Currency',
_closed: false,
opts: [Object],
name: 'currencies',
collectionName: 'currencies',
conn: [NativeConnection],
queue: [],
buffer: false,
emitter: [EventEmitter]
},
collectionName: 'currencies'
},
_traceFunction: undefined,
'$useProjection': true
}
CodePudding user response:
Mongoose has an option for Schemas called strictQuery. If this value is set to true
, fields in the filter that are not part of the schema will be removed from the filter. Its default value is equal to the value of the option strict, which is true
by default.
const mySchema = new Schema({ field: Number }, { strict: true }); const MyModel = mongoose.model('Test', mySchema); // Mongoose will filter out `notInSchema: 1` because `strict: true`, > meaning this query will return // _all_ documents in the 'tests' collection MyModel.find({ notInSchema: 1 });
If you set strictQuery
to false
, fields that don't exist should remain as part of the filter.
const mySchema = new Schema({ field: Number }, { strict: true, strictQuery: false // Turn off strict mode for query filters }); const MyModel = mongoose.model('Test', mySchema); // Mongoose will strip out `notInSchema: 1` because `strictQuery` is false MyModel.find({ notInSchema: 1 });
(There is a comment in the code above stating that Mongoose will strip out notInSchema
, but I believe this may be an error in the documentation, given the previous example with strict
)