วิธีการค้นหาของพังพอนด้วย $ หรือเงื่อนไขทำงานไม่ถูกต้อง


116

เมื่อเร็ว ๆ นี้ฉันเริ่มใช้ MongoDB กับ Mongoose บน Nodejs

เมื่อฉันใช้เมธอด Model.find กับ$orเงื่อนไขและ_idฟิลด์พังพอนทำงานไม่ถูกต้อง

สิ่งนี้ใช้ไม่ได้:

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

อย่างไรก็ตามถ้าฉันลบส่วน '_id' สิ่งนี้จะได้ผล!

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

และใน MongoDB shell ทั้งสองอย่างทำงานได้อย่างถูกต้อง

คำตอบ:


211

ฉันแก้ไขผ่าน 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
คุณช่วยอธิบายได้ไหมว่าทำไมโซลูชันนี้จึงใช้ได้กับคำ ขอบคุณ
Alexander Mills

นี่ดูเหมือนวิธีแก้ปัญหาที่ค่อนข้างเฉพาะเจาะจง คุณอาจต้องค้นหาต่อไป
Kesarion

คุณสามารถให้ข้อมูลอ้างอิงของคุณได้หรือไม่? เหตุใดในกรณีนี้พารามิเตอร์จึงต้องมีอักขระมากกว่า 12 ตัว นี่เป็นปัญหาเฉพาะของคุณหรือข้อกำหนดของ ObjectId () หรือไม่ จะเกิดอะไรขึ้นถ้าพารามิเตอร์ของฉันไม่มีอักขระ 12 ตัว? ขอบคุณ!
yusong

6
คุณยังสามารถตรวจสอบ ObjectId ดังต่อไปนี้:const mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid(objectidtocheck)
Orhan

@yusong เป็นเพราะพังพอนจะทำให้เกิดข้อผิดพลาดหากไม่ใช่ ObjectId ที่ถูกต้อง วิธีที่สะอาดกว่าในการทำดังกล่าวข้างต้นฉัน
Haydar Ali Ismail

53

ฉันขอวิงวอนให้ทุกคนใช้ภาษาตัวสร้างแบบสอบถามของ Mongoose และสัญญาแทนการเรียกกลับ:

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

อ่านเพิ่มเติมเกี่ยวกับพังพอนแบบสอบถาม


รักเลย! ขอบคุณสำหรับหัวขึ้น!
zeckdude

0

ตามเอกสาร mongoDB: "... นั่นคือเพื่อให้ MongoDB ใช้ดัชนีในการประเมิน $ หรือนิพจน์อนุประโยคทั้งหมดใน $ หรือนิพจน์ต้องได้รับการสนับสนุนโดยดัชนี"

ดังนั้นเพิ่มดัชนีสำหรับฟิลด์อื่น ๆ ของคุณและมันจะได้ผล ฉันมีปัญหาที่คล้ายกันและสิ่งนี้แก้ไขได้

สามารถอ่านเพิ่มเติมได้ที่นี่: https://docs.mongodb.com/manual/reference/operator/query/or/


1
นี่เป็นคำสั่งที่ไม่ถูกต้องคุณต้องใช้ดัชนีหากคุณต้องการดัชนีเพื่อใช้เช่นเพื่อประสิทธิภาพเพื่อหลีกเลี่ยงการสแกนคอลเลคชัน แต่ถ้าประสิทธิภาพไม่ใช่ปัญหา (เช่นของสะสมค่อนข้างเล็ก) ก็ไม่เป็นไร ..
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
คำตอบของคุณแตกต่างจากคำตอบของ Govind Rai อย่างไร? อะไรทำให้คุณเหนือกว่าพวกเขา?
BDL

async / รอไม่มีอะไรทำให้เหนือกว่า?
Firez

2
โดยทั่วไปคำตอบที่ใช้รหัสเท่านั้นจะอยู่ในเว็บไซต์นี้ คุณช่วยแก้ไขคำตอบของคุณให้มีความคิดเห็นหรือคำอธิบายโค้ดของคุณได้ไหม คำอธิบายควรตอบคำถามเช่น: มันทำอะไร? มันทำได้อย่างไร? ไม่ไปไหน วิธีแก้ปัญหาของ OP ดู: วิธีการ Anwser ขอบคุณ!
Eduardo Baitello
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.