mongodb / mongoose findMany - tìm tất cả các tài liệu có ID được liệt kê trong mảng


246

Tôi có một mảng _ids và tôi muốn có được tất cả các tài liệu phù hợp, cách tốt nhất để làm điều đó là gì?

Cái gì đó như ...

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

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

Mảng có thể chứa hàng trăm _ids.

Câu trả lời:


479

Các findchức năng trong mongoose là một truy vấn đầy đủ để MongoDB. Điều này có nghĩa là bạn có thể sử dụng $inmệnh đề mongoDB tiện dụng , hoạt động giống như phiên bản SQL giống nhau.

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

Phương pháp này sẽ hoạt động tốt ngay cả đối với các mảng chứa hàng chục nghìn id. (Xem Xác định hiệu quả chủ sở hữu của một bản ghi )

Tôi muốn giới thiệu rằng bất kỳ ai làm việc với việc mongoDBđọc qua phần Truy vấn nâng cao của Tài liệu mongoDB chính thức tuyệt vời


9
Khá muộn cho cuộc thảo luận này, nhưng làm thế nào bạn có thể đảm bảo thứ tự của các mục được trả về khớp với thứ tự của mảng các mục bạn cung cấp trong mảng? Tài liệu không được đảm bảo để đi ra theo bất kỳ thứ tự nào trừ khi bạn chỉ định một loại. Điều gì sẽ xảy ra nếu bạn muốn chúng được sắp xếp theo cùng thứ tự bạn liệt kê chúng trong mảng (ví dụ ... 000c, ... 000d, ... 000e)?
Kevin

7
Điều này đã không làm việc vì một số lý do. Tôi nhận được một mảng trống các tài liệu
chovy

2
@chovy thử chuyển đổi chúng thành ObjectIds trước, thay vì truyền chuỗi.
Georgi Hristozov

@GeorgiHristozov Tôi đang sử dụng trình tạo id tùy chỉnh ... việc chuyển đổi sang ObjectId có còn hoạt động không? (mongoose + shortid)
chovy

1
@Schybo mà làm cho hoàn toàn không có sự khác biệt. { _id : 5 }cũng giống như { '_id' : 5 }.
royhowie

27

Id là mảng của id đối tượng:

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

Sử dụng Mongoose với gọi lại:

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

Sử dụng Mongoose với chức năng async:

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

Đừng quên thay đổi Mô hình với mô hình thực tế của bạn.


Đây phải là câu trả lời được chấp nhận vì nó là câu trả lời cập nhật và mạch lạc nhất. Bạn không phải chuyển đổi id thành ObjectId như trong câu trả lời được chấp nhận và nó sử dụng các truy vấn kiểu bắt buộc cầy mangut . Cảm ơn btw!
Javi Marzán

Đây là một phương pháp rất sạch sẽ và được cập nhật, nếu bạn không muốn hỏi một vài câu hỏi, nếu tôi có một loạt các tham chiếu ObjectIdgiống như ở trên (giả sử, tôi có các dự án và tôi đã chỉ định một mảng dự án cho một số người dùng nhất định với project_id được tham chiếu trên mô hình người dùng), nếu tôi xóa một dự án, làm cách nào để đảm bảo idxóa khỏi mảng được tham chiếu từ mô hình người dùng? Cảm ơn mat.
Eazy

9

Sử dụng định dạng truy vấn này

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

Cả node.js và MongoChef đều buộc tôi phải chuyển đổi sang ObjectId. Đây là những gì tôi sử dụng để lấy danh sách người dùng từ DB và tìm nạp một vài thuộc tính. Hãy nhớ chuyển đổi loại trên dòng 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 (danh sách, chức năng (userId) {return mongoose.Types.ObjectId (userId)};
Michael Draper

1
Tôi đã không phải chuyển đổi sang ObjectID bằng cách sử dụng mongoose 4.5.9.
Florian Wendelborn
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.