mongodb / mongoose findMany-查找ID列在数组中的所有文档


246

我有一个_ids数组,我想相应地获取所有文档,最好的方法是什么?

就像是 ...

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

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

该数组可能包含数百个_id。

Answers:


479

findmongoose中的函数是对mongoDB的完整查询。这意味着您可以使用方便的mongoDB $in子句,该子句的工作方式与SQL版本相同。

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

即使对于包含成千上万个id的数组,此方法也将很好地工作。(请参阅有效确定记录的所有者

我建议任何与工作有关的人员通读优秀的mongoDB官方文档的mongoDB高级查询”部分。


9
在本讨论的后期,您如何确保返回的项目的顺序与您在数组中提供的项目的顺序相匹配?除非您指定种类,否则不能保证文件会以任何顺序出现。如果希望它们以相同的顺序排序,然后在数组中列出它们(例如... 000c,... 000d,... 000e)怎么办?
凯文

7
由于某些原因,这没有用。我有大量的文档
chovy,2014年

2
@chovy尝试先将它们转换为ObjectId,而不是传递字符串。
Georgi Hristozov

@GeorgiHristozov我使用的是自定义ID生成器...转换为ObjectId是否仍然有效?(猫鼬+矮个子)
chovy 2014年

1
@Schybo绝对没有区别。{ _id : 5 }与相同{ '_id' : 5 }
royhowie

27

Ids是对象ID的数组:

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

使用Mongoose进行回调:

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

将Mongoose与异步功能配合使用:

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

不要忘记用实际模型更改模型。


这应该是公认的答案,因为它是最新且连贯的答案。您不必像接受的答案中那样将id转换为ObjectId,它使用猫鼬命令式样式查询。谢谢顺便说一句!
哈维·

这是一个非常干净和更新的方法,如果您不介意的话,我想问几个问题,如果我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(list,function(userId){return mongoose.Types.ObjectId(userId)};
Michael Draper

1
我不必使用猫鼬4.5.9转换为ObjectID。
Florian Wendelborn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.