Arrays 嵌入文档数组中的MongoDB聚合ObjectId

Arrays 嵌入文档数组中的MongoDB聚合ObjectId,arrays,mongodb,mongodb-query,aggregation-framework,Arrays,Mongodb,Mongodb Query,Aggregation Framework,关于ObjectId数组的$lookup聚合器,我已经看到了很多问题,但我似乎找不到任何关于ObjectId何时位于嵌入文档数组中的信息 我在mongodb数据库中有以下文档: _id: ObjectId('...') Alarms: [ { Gateway: ObjectId('...') Port: 1 }, { Gateway: ObjectId('...') Port: 2 } ] 我希望有以下资料: _id: ObjectId('...

关于ObjectId数组的
$lookup
聚合器,我已经看到了很多问题,但我似乎找不到任何关于ObjectId何时位于嵌入文档数组中的信息

我在mongodb数据库中有以下文档:

_id: ObjectId('...')
Alarms: [
  {
    Gateway: ObjectId('...')
    Port: 1
  },
  {
    Gateway: ObjectId('...')
    Port: 2
  }
]
我希望有以下资料:

_id: ObjectId('...')
Alarms [
  {
    Gateway: ...(Gateway Object),
    Port: 1
  },
  {
    Gateway: ...(Gateway Object),
    Port: 2
  }
]
我尝试了以下方法,但没有成功:

$lookup: {
  from: 'Gateway',
  localField: 'Alarms.Gateway',
  foreignField: '_id',
  as: 'Alarms.Gateway'
}
但这给了我以下结果:

_id: ObjectId('...')
Alarms [
  {
    Gateway: {
      ...(Gateway Object)
    }
    Port: 1
  }
]

请尝试以下查询:

如果您不希望在最终结果中,
报警
数组中存在在
网关
集合中不匹配的对象:

db.Alarms.aggregate([{ $unwind: '$Alarms' }, {
    $lookup: {
        from: 'Gateway',
        localField: 'Alarms.Gateway',
        foreignField: '_id',
        as: 'Alarms.Gateway'
    }
}, { $match: { 'Alarms.Gateway': { $ne: [] } } },
{ $addFields: { 'Alarms.Gateway': { $arrayElemAt: ['$Alarms.Gateway', 0] } } },
{ $group: { _id: '$_id', Alarms: { $push: '$Alarms' } } }
])
测试:

否则,如果希望返回
报警
数组中的所有对象,而不管
网关
中是否存在匹配项:

db.Alarms.aggregate([{ $unwind: '$Alarms' }, {
    $lookup: {
        from: 'Gateway',
        localField: 'Alarms.Gateway',
        foreignField: '_id',
        as: 'Alarms.GatewayObj'
    }
}, { $addFields: { 'Alarms.Gateway': { $cond: [{ $ne: ['$Alarms.GatewayObj', []] }, { $arrayElemAt: ['$Alarms.GatewayObj', 0] }, '$Alarms.Gateway'] } } },
{ $project: { 'Alarms.GatewayObj': 0 } },
{ $group: { _id: '$_id', Alarms: { $push: '$Alarms' } } }
])
测试:

两个查询之间的区别是,一个查询将返回
报警中对象下方的值,而另一个查询则不返回

{
    "Gateway": ObjectId("5e2b5425d02e05b6940de2fb"),
    "Port": 2
 }

如果在
报警
中有第三个对象,如
网关
中没有匹配文档的
{Gateway:ObjectId('…')、Port:3}
,会发生什么?您是否仍要将其保留在
报警中作为最终结果,还是删除该项并仅保留具有匹配项的对象?将
更改为:'Alarms.Gateway'
改为
为:'Alarms'