Metode find Mongoose dengan $ atau condition tidak berfungsi dengan baik


116

Baru-baru ini saya mulai menggunakan MongoDB dengan Mongoose di Nodejs.

Ketika saya menggunakan metode Model.find dengan $or kondisi dan _idbidang, Mongoose tidak berfungsi dengan baik.

Ini tidak bekerja:

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

Ngomong-ngomong, jika saya menghapus bagian '_id', ini TIDAK berhasil!

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

Dan di shell MongoDB, keduanya bekerja dengan baik.

Jawaban:


211

Saya menyelesaikannya melalui 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
dapatkah Anda menjelaskan mengapa solusi ini bekerja dengan kata-kata? terima kasih
Alexander Mills

Sepertinya ini solusi untuk masalah yang agak spesifik. Anda mungkin harus terus mencari.
Kesarion

Bisakah Anda memberikan referensi Anda? Mengapa dalam hal ini param harus terdiri lebih dari 12 karakter? Apakah ini khusus untuk masalah Anda atau persyaratan ObjectId ()? Bagaimana jika param saya tidak memiliki 12 karakter? Terima kasih!
yusong

6
Anda juga dapat memeriksa ObjectId sebagai berikut:const mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid(objectidtocheck)
Orhan

@yusong itu karena luwak akan melempar kesalahan jika itu bukan ObjectId yang valid. Cara yang lebih bersih untuk melakukannya yang disebutkan di atas saya.
Haydar Ali Ismail

53

Saya mohon semua orang untuk menggunakan bahasa dan janji pembuat kueri Mongoose alih-alih callback:

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

Baca lebih lanjut tentang Permintaan Mongoose .


Suka! Terimakasih atas peringatannya!
zeckdude

0

Menurut dokumentasi mongoDB: "... Artinya, agar MongoDB menggunakan indeks untuk mengevaluasi $ atau ekspresi, semua klausa dalam $ or ekspresi harus didukung oleh indeks."

Jadi tambahkan indeks untuk bidang Anda yang lain dan itu akan berhasil. Saya memiliki masalah serupa dan ini menyelesaikannya.

Anda dapat membaca lebih lanjut di sini: https://docs.mongodb.com/manual/reference/operator/query/or/


1
ini adalah pernyataan yang salah - Anda hanya memerlukan indeks JIKA Anda memerlukan indeks untuk digunakan - yaitu untuk kinerja, untuk menghindari pemindaian koleksi. Tetapi jika kinerja tidak menjadi masalah (misalnya koleksinya cukup kecil), maka tidak masalah ..
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
Bagaimana jawaban Anda berbeda dari yang diberikan oleh Govind Rai? Apa yang membuat Anda lebih unggul dari mereka?
BDL

async / await, tidak ada yang membuatnya lebih unggul?
Firez

2
Jawaban kode-saja umumnya tidak disukai di situs ini. Bisakah Anda mengedit jawaban Anda untuk menyertakan beberapa komentar atau penjelasan tentang kode Anda? Penjelasan harus menjawab pertanyaan seperti: Apa fungsinya? Bagaimana cara melakukannya? Kemana perginya? Bagaimana cara mengatasi masalah OP? Lihat: Bagaimana menjawab . Terima kasih!
Eduardo Baitello
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.