Метод пошуку 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.