【问题标题】:MongoDB Aggregate ObjectId inside Array of embedded DocumentsMongoDB在嵌入式文档数组中聚合ObjectId
【发布时间】:2020-01-24 20:24:26
【问题描述】:

我已经看到很多关于 $lookup ObjectIds 数组聚合器的问题,但我似乎找不到任何关于 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
  }
]

【问题讨论】:

  • 如果您在Alarms 中有第三个对象,如{ Gateway: ObjectId('...'), Port: 3 },但在Gateway 中没有匹配的文档,会发生什么?您是否仍希望将其保留在 Alarms 数组中作为最终结果还是删除它并仅保留具有匹配项的对象?
  • 把as: 'Alarms.Gateway'改成as: 'Alarms'

标签: arrays mongodb mongodb-query aggregation-framework


【解决方案1】:

请尝试以下查询:

如果您不希望 Gateway 集合中不匹配的对象存在于最终结果中的 Alarms 数组中:

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' } } }
])

测试:MongoDB-Playground

否则,如果您希望返回 Alarms 数组中的所有对象,而不管 Gateway 中是否存在匹配项:

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' } } }
])

测试:MongoDB-Playground

两个查询之间的区别在于一个将返回Alarms数组中的对象下方(Vs)一个不返回。

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

【讨论】:

    猜你喜欢
    • 2013-09-18
    • 1970-01-01
    • 2021-10-24
    • 2019-05-20
    • 2019-05-10
    • 1970-01-01
    • 2017-07-31
    • 2019-02-16
    • 2011-06-02
    相关资源
    最近更新 更多