user1760025
user1760025

Reputation: 297

Mongoose query where with missing (or undefined) fields

I have an issue that I have a messy MongoDB database with a revised Mongoose scheme.

I want to be able to query using the where command, but if the field is missing or undefined in any found record then Mongoose returns an error.

For instance:

  return this.find({personID: req.user._id})
  .where('rangeBefore').lt(time);

This returns an error because some records do not have rangeBefore.

What I want to achieve is that any record without the rangeBefore field is filtered out (i.e. it fails the where test).

I have tried prefixing with exists like this:

  return this.find({personID: req.user._id})
  .exists('rangeBefore').where('rangeBefore').lt(time);

but I still get an error.

Can anyone suggest a way to ignore records with undefined fields, rather than returning an error?

Upvotes: 16

Views: 34412

Answers (3)

JohnnyHK
JohnnyHK

Reputation: 312115

Your error message of:

Cast to number failed for value "undefined" at path "rangeBefore"

means that your time variable is undefined. A query like this will naturally ignore docs where rangeBefore doesn't exist.

So the problem is with your time variable, not your docs or query.

Upvotes: 1

Felipe Pereira
Felipe Pereira

Reputation: 12320

If you just want to modify your existing query:

return this.find({ personID: req.user._id, 
  rangeBefore: { $exists: true, $ne: null } //also check for nulls
})
.where('rangeBefore').lt(time);

Or you can use the callback approach too if it fits:

this.find({personID: req.user._id, 
  rangeBefore: { $exists: true, $ne: null, $lt: time } 
})
.exec(function(err, record) { });

Upvotes: 27

Yuri Zarubin
Yuri Zarubin

Reputation: 11677

You can do it like this, which returns a promise:

find({rangeBefore: { $exists: 1, $lt: time } }).exec()

Or use a callback:

find({rangeBefore: { $exists: 1, $lt: time } }).exec(function(err, record){

})

Upvotes: 3

Related Questions