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.

Younghan
sumber

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);
});
Younghan
sumber
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 .

Govind Rai
sumber
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/

Farasi78
sumber
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 */
Firez
sumber
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