如何使用另一个对象的数组找到具有匹配ID的所有文档

How can I find all documents with a matching ID using an array of another object?

本文关键字:ID 文档 何使用 一个对象 数组      更新时间:2023-09-26

我有两个型号,AlarmAlert

AlertSchema有一个引用Alarm对象id的created_by字段。

给定一个Alarm对象数组,我如何找到所有相应的警报?

这不能工作(我并没有真正期望它)

// Get array of alarm objects
Alarm.find({unit: req.unit._id}).exec(function(err, alarms){
   // Use array of alarm objects to find all alerts
   Alert.find({created_by: alarms})

是我最好的选择,从每个对象提取_id到一个数组,并传递它作为一个参数,像这样:

    Alarm.find({unit: req.unit._id}).exec(function(err, alarms){
   var alarm_ids = alarms.map(function(o){return o._id});
   // Use array of alarm objects to find all alerts
   Alert.find({created_by: alarm_ids})

实际上可以使用 $lookup 操作符使用聚合框架和查询,这使得可以对另一个集合进行左外连接。

检查以下示例:

Alarm.aggregate([
    { "$match": { "unit": req.unit._id } },
    {
        "$lookup": {
            "from": "alerts",
            "localField": "_id",
            "foreignField": "created_by",
            "as": "alarm_alert"
        }
    },
    { "$unwind": "$alarm_alert "}
]).exec(function(err, result){
    console.log(JSON.stringify(result, null, 4));
});

上面的查询是高效的,因为它是一个原子查询,并且使用了本地操作符。


在您的解决方案尝试中,您错过了 $in 操作符,作为拼图拼图的最终匹配,但有一件事让您感到遗憾的是,您正在重复调用服务器,即一次检索警报对象,另一次查询警报集合,因此它可能不如上述聚合操作高效:

Alarm.find({ "unit": req.unit._id })
      .lean() // <-- return plain javascript objects
      .exec(function(err, alarms){
            var alarm_ids = alarms.map(function(o){return o._id});
            // Use array of alarm objects to find all alerts
            Alert.find({ "created_by": { "$in": alarm_ids } }).exec(callback);
       });