Metoda wyszukiwania Mongoose z $ lub warunkiem nie działa poprawnie


116

Ostatnio zacząłem używać MongoDB z Mongoose na Nodejs.

Kiedy używam metody Model.find z $orwarunkiem i _idpolem, Mongoose nie działa poprawnie.

To nie działa:

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

Nawiasem mówiąc, jeśli usunę część „_id”, TO DZIAŁA!

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

W powłoce MongoDB oba działają poprawnie.

Odpowiedzi:


211

Rozwiązałem to przez googlowanie:

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
czy możesz opisać, dlaczego to rozwiązanie działa ze słowami? dzięki
— Alexander Mills,

Wygląda to na rozwiązanie dość konkretnego problemu. Być może będziesz musiał szukać dalej.
— Kesarion

Czy możesz podać swoje referencje? Dlaczego w tym przypadku parametr musi mieć więcej niż 12 znaków? Czy jest to specyficzne dla Twojego problemu lub wymagania ObjectId ()? Co jeśli mój parametr nie ma 12 znaków? Dzięki!
— yusong

6
możesz również sprawdzić ObjectId w następujący sposób:const mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid(objectidtocheck)
— Orhan

@yusong, to spowodowane przez mangustę, wyświetli błąd, jeśli nie jest prawidłowym identyfikatorem obiektu. Czystszy sposób na zrobienie tego wspomniany powyżej.
— Haydar Ali Ismail

53

Błagam wszystkich o używanie języka konstruktora zapytań Mongoose i obietnic zamiast wywołań zwrotnych:

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

Przeczytaj więcej o zapytaniach Mongoose .


Kocham to! Dzięki za ostrzeżenie!
— zeckdude

0

Zgodnie z dokumentacją mongoDB: „... Oznacza to, że aby MongoDB używał indeksów do oceny $ lub wyrażenia, wszystkie klauzule w $ lub wyrażeniu muszą być obsługiwane przez indeksy”.

Więc dodaj indeksy dla innych pól i zadziała. Miałem podobny problem i to go rozwiązało.

Możesz przeczytać więcej tutaj: https://docs.mongodb.com/manual/reference/operator/query/or/


1
to jest błędne stwierdzenie - potrzebujesz indeksów tylko JEŚLI potrzebujesz indeksów do użycia - tj. do wydajności, aby uniknąć skanowania kolekcji. Ale jeśli wydajność nie jest problemem (np. Kolekcja jest dość mała), to nie ma znaczenia ...
— Andy Lorenz

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
Czym różni się twoja odpowiedź od odpowiedzi Govinda Rai? Co sprawia, że ​​twój jest lepszy od ich?
— BDL

async / await, nic nie czyni go lepszym?
— Firez

2
Odpowiedzi zawierające tylko kod są generalnie mile widziane na tej stronie. Czy mógłbyś zmodyfikować swoją odpowiedź, aby zawierała komentarze lub wyjaśnienia dotyczące kodu? Wyjaśnienia powinny odpowiadać na pytania typu: Co to robi? Jak to się dzieje? Dokąd to zmierza? Jak rozwiązuje problem OP? Zobacz: Jak odpowiedzieć . Dzięki!
— Eduardo Baitello
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.