Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 860
user1760025 Avatar asked Feb 20 '15 16:02

user1760025


People also ask

Can Mongoose queries be chained?

The Mongoose Query class provides a chaining interface for finding, updating, and deleting documents.

Can I use $in in Mongoose?

For example, if we want every document where the value of the name field is more than one value, then what? For such cases, mongoose provides the $in operator. In this article, we will discuss how to use $in operator. We will use the $in method on the kennel collection.

What is findById in Mongoose?

We use findById() to find a document whose _id field we create as 6120216fbb75d313c4d65af4 . If the document found is found, then the document is returned. Otherwise, null is returned. RELATED TAGS. mongoose.

Does find return an array Mongoose?

and it will return array? find returns an array always.


3 Answers

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) { });
like image 85
Felipe Pereira Avatar answered Oct 12 '22 09:10

Felipe Pereira


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){

})
like image 37
Yuri Zarubin Avatar answered Oct 12 '22 08:10

Yuri Zarubin


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.

like image 1
JohnnyHK Avatar answered Oct 12 '22 08:10

JohnnyHK