mongodb / mongoose findMany - temukan semua dokumen dengan ID yang tercantum dalam array

246

Saya memiliki serangkaian _id dan saya ingin mendapatkan semua dokumen yang sesuai, apa cara terbaik untuk melakukannya?

Sesuatu seperti ...

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

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

Array mungkin berisi ratusan _ids.

ezmilhouse
sumber

Jawaban:

479

The findfungsi dalam luwak adalah query penuh untuk MongoDB. Ini berarti Anda dapat menggunakan $inklausa mongoDB berguna , yang berfungsi seperti versi SQL yang sama.

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

Metode ini akan bekerja dengan baik bahkan untuk array yang berisi puluhan ribu id. (Lihat Secara efisien menentukan pemilik catatan )

Saya akan merekomendasikan bahwa siapa pun yang bekerja dengan mongoDBmembaca bagian Pertanyaan Tingkat Lanjut dari mongoDB Documents resmi yang sangat baik

Daniel Mendel
sumber
9
Agak terlambat untuk diskusi ini, tetapi bagaimana Anda memastikan urutan barang yang dikembalikan cocok dengan urutan array barang yang Anda berikan dalam array? Dokumen tidak dijamin akan keluar dalam urutan apa pun kecuali Anda menentukan jenis. Bagaimana jika Anda ingin mereka diurutkan dalam urutan yang sama dengan yang Anda daftarkan dalam array (mis. ... 000c, ... 000d, ... 000e)?
Kevin
7
Ini tidak berhasil karena suatu alasan. Saya mendapat deretan dokumen kosong
chovy
2
@chovy coba mengonversinya menjadi ObjectIds terlebih dahulu, alih-alih meneruskan string.
Georgi Hristozov
@GeorgiHristozov saya menggunakan generator id kustom ... apakah konversi ke ObjectId masih berfungsi? (luwak + shortid)
chovy
1
@Sybo yang sama sekali tidak ada bedanya. { _id : 5 }sama dengan { '_id' : 5 }.
royhowie
27

Id adalah array id objek:

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

Menggunakan Mongoose dengan panggilan balik:

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

Menggunakan Mongoose dengan fungsi async:

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

Jangan lupa untuk mengubah Model dengan model Anda yang sebenarnya.

SnnSnn
sumber
Ini harus menjadi jawaban yang diterima karena merupakan yang paling mutakhir dan koheren. Anda tidak harus mengonversi id ke ObjectId seperti pada jawaban yang diterima, dan ia menggunakan kueri gaya imperatif luwak . Terima kasih btw!
Javi Marzán
Ini adalah metode yang sangat bersih dan diperbarui, jika Anda tidak keberatan saya ingin mengajukan beberapa pertanyaan, jika saya memiliki array yang direferensikan ObjectIdseperti di atas (katakanlah, saya punya proyek, dan saya menetapkan array dari memproyeksikan ke pengguna tertentu dengan project_id direferensikan pada model pengguna), jika saya menghapus proyek, bagaimana saya memastikan iddihapus dari array yang dirujuk dari model pengguna? Terima kasih mat.
Eazy
9

Gunakan format kueri ini

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();
Derese Getachew
sumber
4

Baik node.js dan MongoChef memaksa saya untuk mengonversi ke ObjectId. Ini yang saya gunakan untuk mengambil daftar pengguna dari DB dan mengambil beberapa properti. Pikirkan jenis konversi pada baris 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 );
                }
            }
        });
    }
Nico
sumber
7
userIds = _.map (daftar, fungsi (userId) {return mongoose.Types.ObjectId (userId)};
Michael Draper
1
Saya tidak perlu mengonversi ke ObjectID menggunakan luoose 4.5.9.
Florian Wendelborn