Метод пошуку Mongoose з $ або умовою не працює належним чином


116

Останнім часом я починаю використовувати 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 обидва працюють належним чином.

Відповіді:


211

Я вирішив це через Google:

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
чи можете ви описати, чому це рішення працює словами? дякую
— Олександр Міллс

Це виглядає як вирішення досить конкретного питання. Можливо, вам доведеться продовжувати пошук.
— Кесаріон

Чи можете ви надати свою довідку? Чому в цьому випадку парам повинен містити більше 12 символів? Це специфічно для вашої проблеми чи вимоги ObjectId ()? Що робити, якщо в моєму парамі немає 12 символів? Дякую!
— yusong

6
Ви також можете перевірити ObjectId так:const mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid(objectidtocheck)
— Орхан

@yusong, це пов’язано з мангустом, якщо він не є дійсним ObjectId. Більш чистий спосіб зробити це згаданий вище мною.
— Гайдар Алі Ісмаїл

53

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

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

Детальніше про запити мангустів .


Любіть це! Дякую за голову вгору!
— zeckdude

0

Згідно з документацією mongoDB: "... Тобто для того, щоб MongoDB використовував індекси для оцінки $ або виразу, всі пропозиції в $ або виразі повинні підтримуватися індексами."

Тому додайте індекси для інших ваших полів, і воно буде працювати. У мене була подібна проблема, і це її вирішило.

Більше ви можете прочитати тут: https://docs.mongodb.com/manual/reference/operator/query/or/


1
це неправильне твердження - вам потрібні лише індекси, якщо вам потрібні індекси - тобто для продуктивності, щоб уникнути сканування колекції. Але якщо продуктивність не є проблемою (наприклад, колекція досить мала), то це не має значення ..
— Енді Лоренц

0
async() => {
let body = await model.find().or([
  { name: 'something'},
  { nickname: 'somethang'}
]).exec();
console.log(body);
}
/* Gives an array of the searched query!
returns [] if not found */

1
Чим ваша відповідь відрізняється від відповіді Говінда Рай? Що робить тебе вищим за їх?
— BDL

асинхронізація / очікування, ніщо не робить це вищим?
— Firez

2
Відповіді, що стосуються лише коду, зазвичай нахмурені на цьому сайті. Чи можете ви відредагувати свою відповідь, щоб включити коментарі чи пояснення свого коду? Пояснення повинні відповідати на запитання на кшталт: Що це робить? Як це робиться? Куди воно йде? Як це вирішує проблему ОП? Див.: Як відповісти . Дякую!
— Едуардо Байтело
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.