Recently I start using MongoDB with Mongoose on Nodejs.
When I use Model.find method with $or condition and _id field, Mongoose does not work properly.
This does not work:
User.find({ $or: [ { '_id': param }, { 'name': param }, { 'nickname': param } ] }, function(err, docs) { if(!err) res.send(docs); });
By the way, if I remove the '_id' part, this DOES work!
User.find({ $or: [ { 'name': param }, { 'nickname': param } ] }, function(err, docs) { if(!err) res.send(docs); });
And in MongoDB shell, both work properly.
I solved it through googling:
var ObjectId = require('mongoose').Types.ObjectId; var objId = new ObjectId( (param.length < 12) ? "123456789012" : param ); // You should make string 'param' as ObjectId type. To avoid exception, // the 'param' must consist of more than 12 characters. User.find( { $or:[ {'_id':objId}, {'name':param}, {'nickname':param} ]}, function(err,docs){ if(!err) res.send(docs); });
I implore everyone to use Mongoose's query builder language and promises instead of callbacks:
User.find().or([{ name: param }, { nickname: param }]) .then(users => { /*logic here*/ }) .catch(error => { /*error logic here*/ })
Read more about Mongoose Queries.
According to mongoDB documentation: "...That is, for MongoDB to use indexes to evaluate an $or expression, all the clauses in the $or expression must be supported by indexes."
So add indexes for your other fields and it will work. I had a similar problem and this solved it.
You can read more here: https://docs.mongodb.com/manual/reference/operator/query/or/