【问题标题】:How to populate the sub-documents returned after aggregate lookup in mongodb?如何填充在mongodb中聚合查找后返回的子文档?
【发布时间】:2021-06-03 00:07:15
【问题描述】:

我在 mongodb 中有以下三种模式。

const A = new Schema({
  labelA: String
})

const B = new Schema({
  labelB: String
  refToA: {Schema.Types.ObjectId, ref: 'A'}
  refToCArray: [{Schema.Types.ObjectId, ref: 'C'}]
})

const C = new Schema({
  labelC: String
})

我在 A 中运行以下聚合查询以附加一个名为“BCollection”的字段,该字段包含来自 B 的与 A 的 id 匹配的记录。

const ACollection = await A.aggregate([
  { $match: { labelA: 'LabelA1' } },
  {
    $lookup: {
      from: 'B',
      localField: '_id',
      foreignField: 'refToA',
      as: 'BCollection',
    },
  },
])

我的问题是附加的 B 文档在 'refToCArray' 字段中包含 C 的 ID。我想用 C 中的实际内容“填充”或替换这些 id。我该怎么做?

例子:

// Documents in A:
{_id: 'A_id1', labelA: 'LabelA1'}
{_id: 'A_id2', labelA: 'LabelA2'}

// Documents in B: 
{_id: 'B_id1', labelB: 'LabelB1', refToA: 'A_id1', refToCArray: ['C_id1']}
{_id: 'B_id2', labelB: 'LabelB2', refToA: 'A_id1', refToCArray: ['C_id1']}
{_id: 'B_id3', labelB: 'LabelB3', refToA: 'A_id1', refToCArray: ['C_id1']}
{_id: 'B_id4', labelB: 'LabelB4', refToA: 'A_id2', refToCArray: ['C_id1']}

// Documents in C
C1 {_id: 'C_id1', labelC: 'LabelC'}

以上查询返回以下内容:

[{
  _id: 'A_id1',
  labelA: 'LabelA1'
  BCollection: [
    {_id: 'B_id1', labelB: 'LabelB1', refToA: 'A_id1', refToCArray: ['C_id1']},
    {_id: 'B_id2', labelB: 'LabelB2', refToA: 'A_id1', refToCArray: ['C_id1']},
    {_id: 'B_id3', labelB: 'LabelB3', refToA: 'A_id1', refToCArray: ['C_id1']}
  ]
}]

查询到目前为止我很好,但 refToCArray 包含 Id 列表:C_id1。我想得到如下结果:

  [{
      _id: 'A_id1',
      labelA: 'LabelA1'
      BCollection: [
        {_id: 'B_id1', labelB: 'LabelB1', refToA: 'A_id1', refToCArray: [{_id: 'C_id1', labelC: 'LabelC'}]},
        {_id: 'B_id2', labelB: 'LabelB2', refToA: 'A_id1', refToCArray: [{_id: 'C_id1', labelC: 'LabelC'}]},
        {_id: 'B_id3', labelB: 'LabelB3', refToA: 'A_id1', refToCArray: [{_id: 'C_id1', labelC: 'LabelC'}]}
      ]
    }]

【问题讨论】:

    标签: node.js mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    试试这个:

    db.A.aggregate([
        {
            $lookup: {
                from: "B",
                let: { refToA: "$_id" },
                pipeline: [
                    {
                        $match: {
                            $expr: { $eq: ["$refToA", "$$refToA"] }
                        }
                    },
                    {
                        $lookup: {
                            from: "C",
                            localField: "refToCArray",
                            foreignField: "_id",
                            as: "refToCArray"
                        }
                    }
                ],
                as: "BCollection"
            }
        }
    ]);
    

    【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2018-06-13
    • 2016-01-21
    • 1970-01-01
    • 2023-02-10
    • 2019-10-25
    • 2013-05-06
    • 2021-07-27
    相关资源
    最近更新 更多