首页 > 解决方案 > MongoDB按字段查找对象数组并在结果中保留其他字段

问题描述

我试图弄清楚如何通过特定字段查找对象数组,同时保留与查找字段处于同一级别的其他字段。

我的processes收藏如下:

{
    _id: 'p1',
    steps: [
        {
            _id: 'ps1',
            step: 's1',
            time: 10
        },
        {
            _id: 'ps2',
            step: 's2',
            time: 15
        }
    ]
}

steps集合看起来像(对于带有 的文档_id: s1):

{
    _id: 's1',
    name: 'step 1'
}

我的聚合:

processes.aggregate([
    {
        // match stage or whatever prior stage
    },
    {
        $lookup: {
             from: 'steps',
             localField: 'steps.step',
             foreignField: '_id',
             as: 'steps'
        }
    }
])

这可行,但基本上会删除与查找字段 ( ) 处于同一级别的steps._id和字段,如输出所示:steps.timesteps.step

{
    _id: 'p1',
    steps: [
        {
            _id: 's1',
            name: 'step 1'
        },
        {
            _id: 's2',
            name: 'step 2'
        }
    ]
}

虽然预期的输出是:

{
    _id: 'p1',
    steps: [
        {
            _id: 'ps1',
            time: 10,
            stepId: 's1',
            name: 'step 1',
        },
        {
            _id: 'ps2',
            time: 15,
            stepId: 's2',
            name: 'step 2',
        }
    ]
}

注意_id预期输出中的字段不是很重要,可以包含step文档的_id,避免有单独的stepId字段。

编辑

附加问题移至此处:MongoDB lookup array of objects by field (join conditions and uncorrelated sub-queries)

标签: mongodbmongodb-queryaggregation-framework

解决方案


经过大量研究,我可以找到实现我在问题中的意思的方法。

主要思想是将两个对象数组合并在一起。

processes.aggregate([
    {
        // match stage or whatever prior stage
    },
    {
        $lookup: {
             from: 'steps',
             localField: 'steps.step',
             foreignField: '_id',
             as: 'steps2'
        },
        {
            $addFields: {
              stages: {
                $map: {
                  input: '$steps',
                    in: {
                      $mergeObjects: [
                        '$$this',
                        {
                          $arrayElemAt: [
                            '$steps2',
                            {
                              $indexOfArray: ['$steps2._id', '$$this.step'],
                            },
                          ],
                        },
                      ],
                    },
                  },
                },
              },
        }
    }
])

推荐阅读