Home > OS >  Mongoose findOne() and find() return invalid values, when they should return null / empty list respe
Mongoose findOne() and find() return invalid values, when they should return null / empty list respe

Time:12-23

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)

  • Related