mongodb / พังพอน findMany - ค้นหาเอกสารทั้งหมดที่มี ID ที่แสดงรายการในอาร์เรย์


246

ฉันมีชุดของ _ids และฉันต้องการให้เอกสารทั้งหมดสอดคล้องกันวิธีที่ดีที่สุดในการทำคืออะไร

สิ่งที่ต้องการ ...

// doesn't work ... of course ...

model.find({
    '_id' : [
        '4ed3ede8844f0f351100000c',
        '4ed3f117a844e0471100000d', 
        '4ed3f18132f50c491100000e'
    ]
}, function(err, docs){
    console.log(docs);
});

อาร์เรย์อาจมี _ids หลายร้อยรายการ

คำตอบ:


479

findฟังก์ชั่นในพังพอนเป็นแบบสอบถามที่เต็มไป MongoDB ซึ่งหมายความว่าคุณสามารถใช้$inประโยคmongoDB ที่มีประโยชน์ซึ่งทำงานได้เหมือนกับ SQL เวอร์ชันเดียวกัน

model.find({
    '_id': { $in: [
        mongoose.Types.ObjectId('4ed3ede8844f0f351100000c'),
        mongoose.Types.ObjectId('4ed3f117a844e0471100000d'), 
        mongoose.Types.ObjectId('4ed3f18132f50c491100000e')
    ]}
}, function(err, docs){
     console.log(docs);
});

วิธีนี้จะทำงานได้ดีแม้กับอาร์เรย์ที่มีรหัสหมื่นไอดี (ดูที่การกำหนดเจ้าของระเบียนอย่างมีประสิทธิภาพ )

ฉันอยากจะแนะนำให้ทุกคนที่ทำงานกับmongoDBอ่านผ่านขั้นสูงแบบสอบถามของเอกสาร mongoDB อย่างเป็นทางการที่ยอดเยี่ยม


9
การสนทนาสายนี้ช้าแค่ไหน แต่คุณจะมั่นใจได้อย่างไรว่าคำสั่งของรายการที่ส่งคืนตรงกับลำดับของรายการที่คุณให้ไว้ในอาร์เรย์ เอกสารจะไม่รับประกันว่าจะออกมาในลำดับใด ๆ เว้นแต่คุณจะระบุการเรียงลำดับ จะเป็นอย่างไรถ้าคุณต้องการเรียงลำดับแบบเดียวกันกับที่คุณเรียงไว้ในอาร์เรย์ (เช่น ... 000c, ... 000d, ... 000e)
Kevin

7
สิ่งนี้ไม่ทำงานด้วยเหตุผลบางอย่าง ฉันได้รับเอกสารว่างเปล่าจำนวนมาก
chovy

2
@chovy ลองแปลงเป็น ObjectIdsก่อนแทนที่จะส่งผ่านสตริง
Georgi Hristozov

@GeorgiHristozov ฉันใช้ตัวสร้างรหัสที่กำหนดเอง ... การแปลงเป็น ObjectId ยังคงทำงานอยู่หรือไม่ (mongoose + shortid)
chovy

1
@Schybo ที่ทำให้ไม่แตกต่างอย่างแน่นอน เป็นเช่นเดียวกับ{ _id : 5 } { '_id' : 5 }
royhowie

27

Id คืออาร์เรย์ของรหัสวัตถุ:

const ids =  [
    '4ed3ede8844f0f351100000c',
    '4ed3f117a844e0471100000d', 
    '4ed3f18132f50c491100000e',
];

ใช้พังพอนกับโทรกลับ:

Model.find().where('_id').in(ids).exec((err, records) => {});

การใช้พังพอนกับฟังก์ชั่น async:

records = await Model.find().where('_id').in(ids).exec();

อย่าลืมเปลี่ยนโมเดลด้วยโมเดลจริงของคุณ


นี่ควรเป็นคำตอบที่ยอมรับได้เนื่องจากเป็นคำตอบที่ทันสมัยและสอดคล้องกันมากที่สุด คุณไม่จำเป็นต้องแปลงรหัสไปเป็น ObjectId เช่นเดียวกับในคำตอบที่ยอมรับและจะใช้การสอบถามสไตล์ที่จำเป็นแบบพังพอน ขอบคุณ btw!
Javi Marzán

นี่เป็นวิธีที่สะอาดและอัปเดตถ้าคุณไม่รังเกียจฉันอยากถามคำถามสองสามข้อถ้าฉันมีอาร์เรย์ของการอ้างอิงObjectIdดังกล่าวข้างต้น (พูดว่าฉันมีโครงการและฉันได้กำหนดอาร์เรย์ของ โปรเจ็กต์สำหรับผู้ใช้บางรายที่มี project_id ที่อ้างอิงกับโมเดลผู้ใช้) ถ้าฉันลบโปรเจ็กต์ฉันจะแน่ใจได้อย่างไรว่าidจะถูกลบออกจากอาร์เรย์ที่อ้างอิงจากโมเดลผู้ใช้? ขอบคุณจ้า
Eazy

9

ใช้รูปแบบของการสืบค้นนี้

let arr = _categories.map(ele => new mongoose.Types.ObjectId(ele.id));

Item.find({ vendorId: mongoose.Types.ObjectId(_vendorId) , status:'Active'})
  .where('category')
  .in(arr)
  .exec();

4

ทั้ง node.js และ MongoChef บังคับให้ฉันเปลี่ยนเป็น ObjectId นี่คือสิ่งที่ฉันใช้เพื่อคว้ารายชื่อผู้ใช้จากฐานข้อมูลและดึงคุณสมบัติบางอย่าง รังเกียจการแปลงประเภทในบรรทัด 8

// this will complement the list with userName and userPhotoUrl based on userId field in each item
augmentUserInfo = function(list, callback){
        var userIds = [];
        var users = [];         // shortcut to find them faster afterwards
        for (l in list) {       // first build the search array
            var o = list[l];
            if (o.userId) {
                userIds.push( new mongoose.Types.ObjectId( o.userId ) );           // for the Mongo query
                users[o.userId] = o;                                // to find the user quickly afterwards
            }
        }
        db.collection("users").find( {_id: {$in: userIds}} ).each(function(err, user) {
            if (err) callback( err, list);
            else {
                if (user && user._id) {
                    users[user._id].userName = user.fName;
                    users[user._id].userPhotoUrl = user.userPhotoUrl;
                } else {                        // end of list
                    callback( null, list );
                }
            }
        });
    }

7
userIds = _.map (รายการฟังก์ชั่น (userId) {return mongoose.Types.ObjectId (userId)};
Michael Draper

1
ฉันไม่ต้องแปลงเป็น ObjectID โดยใช้ mongoose 4.5.9
Florian Wendelborn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.