Il metodo find di Mongoose con $ o condition non funziona correttamente


116

Recentemente ho iniziato a usare MongoDB con Mongoose su Nodejs.

Quando utilizzo il metodo Model.find con $orcondition e_id campo, Mongoose non funziona correttamente.

Questo non funziona:

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

A proposito, se rimuovo la parte "_id", funziona!

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

E nella shell MongoDB, entrambi funzionano correttamente.

Risposte:


211

L'ho risolto tramite 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
puoi descrivere perché questa soluzione funziona con le parole? grazie
Alexander Mills

Questa sembra una soluzione a un problema piuttosto specifico. Potrebbe essere necessario continuare a cercare.
Kesarion

Potreste fornire il vostro riferimento? Perché in questo caso param deve essere composto da più di 12 caratteri? È specifico per il tuo problema o per il requisito di ObjectId ()? E se il mio parametro non ha 12 caratteri? Grazie!
yusong

6
puoi anche controllare ObjectId come segue:const mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid(objectidtocheck)
Orhan

@yusong è dovuto a mongoose genererà un errore se non è un ObjectId valido. Un modo più pulito per farlo menzionato sopra di me.
Haydar Ali Ismail

53

Imploro tutti di utilizzare il linguaggio di creazione di query di Mongoose e promette invece di richiamate:

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

Ulteriori informazioni sulle query Mongoose .


Lo adoro! Grazie per il testa a testa!
zeckdude

0

Secondo la documentazione di mongoDB: "... Cioè, affinché MongoDB utilizzi gli indici per valutare un $ o un'espressione, tutte le clausole in $ o nell'espressione devono essere supportate dagli indici."

Quindi aggiungi gli indici per gli altri campi e funzionerà. Ho avuto un problema simile e questo lo ha risolto.

Puoi leggere di più qui: https://docs.mongodb.com/manual/reference/operator/query/or/


1
questa è un'affermazione sbagliata - hai bisogno di indici solo SE hai bisogno di indici da usare - cioè per le prestazioni, per evitare una scansione di raccolta. Ma se le prestazioni non sono un problema (ad esempio, la raccolta è piuttosto piccola), allora non importa ..
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
In che modo la tua risposta è diversa da quella di Govind Rai? Cosa rende il tuo superiore al loro?
BDL

async / wait, niente lo rende superiore?
Firez

2
Le risposte di solo codice sono generalmente disapprovate su questo sito. Potresti modificare la tua risposta per includere alcuni commenti o una spiegazione del tuo codice? Le spiegazioni dovrebbero rispondere a domande come: cosa fa? Come lo fa? Dove va? Come risolve il problema di OP? Vedi: Come rispondere . Grazie!
Eduardo Baitello
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.