.find() from Mongoose returns nothing when it should

Asked

Viewed 181 times

0

I’m trying to make an appointment with Mongodb with Mongoose.

The parameter is a $in with an array whose only value is a regular expression that selects the object if the attribute "url" has the string contained in "value" with or without surrounding characters. That is, the regular expression gives match if the searched string is contained in the URL.

However, after the return of promisse from query.exec() what returns is [], an empty array. The point is that I’m sure there is in the bank a doucumento whose url attribute has the value passed contained, the search should return this attribute...

      async function buscarNoBdPorValorContido(model, atributo, valor){
     
        var valores = valor.split(` `)

        valores.forEach(async valor => {

            const query = model.find({url: {'$in': [`/.*${valor}.*`]}})
            console.log(query)
            const documentos = await query.exec()
            console.log(documentos)  //IMPRIME UM ARRAY VAZIO

        })
    }

I can’t see what could be wrong... About Mongo’s $in operator, I found it here: https://docs.mongodb.com/manual/reference/operator/query/in/#use-the-in-Operator-with-a-regular-Expression

When you give console.log() to the query object, the result is this:

Query {
  _mongooseOptions: {},
  _transforms: [],
  _hooks: Kareem { _pres: Map {}, _posts: Map {} },
  _executionCount: 0,
  mongooseCollection: NativeCollection {
    collection: Collection { s: [Object] },
    Promise: [Function: Promise],
    _closed: false,
    opts: {
      bufferCommands: true,
      capped: false,
      autoCreate: undefined,
      Promise: [Function: Promise],
      '$wasForceClosed': undefined
    },
    name: 'noticias',
    collectionName: 'noticias',
    conn: NativeConnection {
      base: [Mongoose],
      collections: [Object],
      models: [Object],
      config: [Object],
      replica: false,
      options: null,
      otherDbs: [],
      relatedDbs: {},
      states: [Object: null prototype],
      _readyState: 1,
      _closeCalled: false,
      _hasOpened: true,
      plugins: [],
      id: 0,
      _listening: false,
      _connectionOptions: [Object],
      name: 'covid-database',
      host: 'localhost',
      port: 27017,
      user: undefined,
      pass: undefined,
      client: [MongoClient],
      '$initialConnection': [Promise],
      db: [Db]
    },
    queue: [],
    buffer: false,
    emitter: EventEmitter {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      [Symbol(kCapture)]: false
    }
  },
  model: Model { Noticia },
  schema: Schema {
    obj: { url: [Function: String] },
    paths: { url: [SchemaString], _id: [ObjectId], __v: [SchemaNumber] },
    aliases: {},
    subpaths: {},
    virtuals: { id: [VirtualType] },
    singleNestedPaths: {},
    nested: {},
    inherits: {},
    callQueue: [],
    _indexes: [],
    methods: {},
    methodOptions: {},
    statics: {},
    tree: {
      url: [Function: String],
      _id: [Object],
      __v: [Function: Number],
      id: [VirtualType]
    },
    query: {},
    childSchemas: [],
    plugins: [ [Object], [Object], [Object], [Object], [Object] ],
    '$id': 1,
    s: { hooks: [Kareem] },
    _userProvidedOptions: { typeKey: '$type' },
    options: {
      typeKey: '$type',
      typePojoToMixed: true,
      id: true,
      noVirtualId: false,
      _id: true,
      noId: false,
      validateBeforeSave: true,
      read: null,
      shardKey: null,
      autoIndex: null,
      minimize: true,
      discriminatorKey: '__t',
      versionKey: '__v',
      capped: false,
      bufferCommands: true,
      strict: true,
      pluralization: true
    },
    '$globalPluginsApplied': true,
    _requiredpaths: []
  },
  op: 'find',
  options: {},
  _conditions: { url: { '$in': [Array] } },
  _fields: undefined,
  _update: undefined,
  _path: undefined,
  _distinct: undefined,
  _collection: NodeCollection {
    collection: NativeCollection {
      collection: [Collection],
      Promise: [Function: Promise],
      _closed: false,
      opts: [Object],
      name: 'noticias',
      collectionName: 'noticias',
      conn: [NativeConnection],
      queue: [],
      buffer: false,
      emitter: [EventEmitter]
    },
    collectionName: 'noticias'
  },
  _traceFunction: undefined,
  '$useProjection': true
}

1 answer

1


One of the problems I see is that you want to query using a regular expression, but are using a string as a parameter.

In the following code line:

const query = model.find({url: {'$in': [`/.*${valor}.*`]}})

`/.*${valor}.*` is just a string, to declare a regular expression, you do not delimit it with quotes, you delimit it with bars: /exemplo/. To generate a regular expression dynamically from a string, you need to use the constructor RegExp.

So in your code it should be

const query = model.find({url: {'$in': [new RegExp(`/.*${valor}.*`)]}})

This regular expression could also be simplified, this bar at the beginning seems to be wrong, and the .* is also redundant for that expression. So you could write simply

const query = model.find({url: {'$in': [new RegExp(valor)]}})

Finally, the operator $in also is redundant if you are looking for only one expression (and not several), could write

const query = model.find({url: new RegExp(valor)})

And if you want to ignore upper and lower case letters, you can add the flag i:

const query = model.find({url: new RegExp(valor, 'i')})
  • thanks for the tips, I’ll start testing them, and I’ll be right back

Browser other questions tagged

You are not signed in. Login or sign up in order to post.