Phương thức tìm kiếm của Mongoose với $ hoặc điều kiện không hoạt động bình thường


116

Gần đây tôi bắt đầu sử dụng MongoDB với Mongoose trên Nodejs.

Khi tôi sử dụng phương thức Model.find với $orđiều kiện và _idtrường, Mongoose không hoạt động bình thường.

Điều này không hoạt động:

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

Nhân tiện, nếu tôi xóa phần '_id', điều này KHÔNG hoạt động!

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

Và trong MongoDB shell, cả hai đều hoạt động bình thường.

Câu trả lời:


211

Tôi đã giải quyết nó thông qua 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
bạn có thể mô tả lý do tại sao giải pháp này hoạt động với các từ? cảm ơn
Alexander Mills

Đây có vẻ như là một giải pháp cho một vấn đề khá cụ thể. Bạn có thể phải tiếp tục tìm kiếm.
Kesarion

Bạn có thể cung cấp tài liệu tham khảo của bạn? Tại sao trong trường hợp này param phải bao gồm nhiều hơn 12 ký tự? Điều này là cụ thể cho vấn đề của bạn hay yêu cầu của ObjectId ()? Điều gì sẽ xảy ra nếu tham số của tôi không có 12 ký tự? Cảm ơn!
yusong

6
bạn cũng có thể kiểm tra ObjectId như sau:const mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid(objectidtocheck)
Orhan

@yusong đó là do mongoose sẽ gây ra lỗi nếu nó không phải là ObjectId hợp lệ. Một cách tốt hơn để làm điều đó đã đề cập ở trên tôi.
Haydar Ali Ismail

53

Tôi kêu gọi mọi người sử dụng ngôn ngữ xây dựng truy vấn của Mongoose và hứa hẹn thay vì gọi lại:

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

Đọc thêm về Mongoose Queries .


Yêu nó! Cảm ơn cho những người đứng đầu lên!
zeckdude

0

Theo tài liệu mongoDB: "... Nghĩa là, để MongoDB sử dụng các chỉ mục để đánh giá một $ hoặc biểu thức, tất cả các mệnh đề trong $ hoặc biểu thức phải được hỗ trợ bởi các chỉ mục."

Vì vậy, hãy thêm chỉ mục cho các trường khác của bạn và nó sẽ hoạt động. Tôi đã có một vấn đề tương tự và điều này đã giải quyết nó.

Bạn có thể đọc thêm tại đây: https://docs.mongodb.com/manual/reference/operator/query/or/


1
đây là một tuyên bố sai - bạn chỉ cần chỉ mục NẾU bạn cần chỉ mục được sử dụng - tức là để thực hiện, để tránh quét bộ sưu tập. Nhưng nếu hiệu suất không phải là một vấn đề (ví dụ như bộ sưu tập khá nhỏ), thì điều đó không quan trọng ..
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
Câu trả lời của bạn khác với câu trả lời của Govind Rai như thế nào? Điều gì khiến bạn vượt trội hơn của họ?
BDL

async / await, không có gì làm cho nó vượt trội?
Firez

2
Các câu trả lời chỉ có mã thường được đưa ra trên trang web này. Bạn có thể vui lòng chỉnh sửa câu trả lời của mình để bao gồm một số nhận xét hoặc giải thích về mã của bạn không? Phần giải thích nên trả lời những câu hỏi như: Nó làm gì? Nó làm điều đó như thế nào? Nó đi đâu? Làm thế nào để nó giải quyết vấn đề của OP? Xem: Làm thế nào để anwser . Cảm ơn!
Eduardo Baitello
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.