Метод поиска Mongoose с условием $или не работает должным образом

Недавно я начал использовать MongoDB с Mongoose на Nodejs.

Когда я использую метод Model.find с условием $or и _id, Mongoose не работает должным образом.

Это не работает:

User.find({
  $or: [
    { '_id': param },
    { 'name': param },
    { 'nickname': param }
  ]
}, function(err, docs) {
   if(!err) res.send(docs);
});

Кстати, если я удаляю часть '_id', это работает!

User.find({
  $or: [
    { 'name': param },
    { 'nickname': param }
  ]
}, function(err, docs) {
   if(!err) res.send(docs);
});

И в оболочке MongoDB обе работают правильно.

Ответ 1

Я решил это через 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);
});

Ответ 2

Я умоляю всех использовать язык построения запросов Mongoose и обещания вместо обратных вызовов:

User.find().or([{ name: param }, { nickname: param }])
    .then(users => { /*logic here*/ })
    .catch(error => { /*error logic here*/ })

Узнайте больше о Mongoose Queries.

Ответ 3

Согласно документации mongoDB: "... То есть, чтобы MongoDB использовал индексы для оценки $или выражения, все предложения в выражении $или expression должны поддерживаться индексами".

Итак, добавьте индексы для других полей, и это сработает. У меня была аналогичная проблема, и это решило ее.

Вы можете прочитать больше здесь: https://docs.mongodb.com/manual/reference/operator/query/or/