首页 > 解决方案 > 我需要从记录集合中以键值对的形式提取数据,并将它们合并到 mongoDB 中的父记录中

问题描述

下面我有一个结构,用于在我的sails.js 应用程序中支持自定义选项列表字段(在此示例中)。总体思路是,我们支持应用程序内任何模型上的自定义选项列表值的集合,并且客户可以完全控制自定义字段的配置。

我采用了这种关系模型,因为在更新每个单独的自定义选项列表值时,使用简单的 json 字段缺乏稳健性。如果我允许客户将“内部”更改为“外部”,我需要使用新值更新针对该自定义选项列表记录的具有“内部”值的所有记录。

这样 - 当我更新CustomPicklistValue通过 ID 引用该记录的任何位置的“值”字段时,它将使用新值。

在此处输入图像描述

现在问题来了,当我需要将此模型集成到我现有的报表引擎中时......

rawCollection
        .aggregate(
            [
                {
                    $match: {
                        createdAt: {
                            $gte: rangeEndDate,
                            $lte: rangeStartDate
                        },
                        ...$match
                    }
                },
                {
                    $project: {
                        ...$project,
                        total: $projectAggregation
                    }
                },
                {
                    $group: {
                        _id: {
                            ...$groupKey
                        },
                        total: {
                            [`$${aggrAttrFunc}`]: "$total"
                        }
                    }
                }
            ],
            {
                cursor: {
                    batchSize: 100
                }
            }
        )

这是检索和聚合存储在我的 mongodb 实例中的任何模型的方法的主要部分。用户可以指定一系列内容,包括但不限于模型、特定字段的日期范围和过滤器,例如“证书状态等于过期”等。

所以我现在看到了这个数据结构:

{
    id: '5e5fb732a9422a001146509f',
    customPicklistValues: [
        {
            id: '5e4e904f16ab94bff1a324a0',
            value: 'Internal',
            fieldName: 'Business Group',
            customPicklist: '109c7a1a9d00b664f2ee7827'
        },
        {
            id: '5e4e904f16ab94bff1a324a4',
            value: 'Slack',
            fieldName: 'Application',
            customPicklist: '109c5a1a9d00b664f2ee7827'
        }
    ],
}

如果有任何方法可以从本质上提取fieldName并将value每个填充的记录作为键值对并在运行匹配子句之前将每个记录添加到父记录中,那么对于我的生活来说,我无法解决......

我想我需要使用查找来最初填充customPicklistValues然后以某种方式合并它们?

任何帮助表示赞赏。

编辑:

@whoami 建议我使用 $addFields。在 $addFields 填充链接记录之前,我需要做很多事情(由于 Waterline 通过sails.js 处理将相关集合中的 Mongo ObjectIDs 保存为字符串),您可以在此处查看我在指南针中的步骤:

在此处输入图像描述

最后一步是编辑它或向它添加一个阶段,以实际能够支持键:值对,就像Business Group: "Finance"本例中一样。

标签: mongodbmongodb-queryaggregation-framework

解决方案


你可以在你的阶段之后尝试这些阶段$lookup

db.collection.aggregate([
    {
        $addFields: {
            customPicklistValues:
            {
                $arrayToObject: {
                    $map: {
                        input: '$customPicklistValues',
                        in: { k: '$$this.fieldName', v: '$$this.value' }
                    }
                }
            }
        }
    },
    { $replaceRoot: { newRoot: { $mergeObjects: ['$customPicklistValues', '$$ROOT'] } } },
    { $project: { customPicklistValues: 0 } }
])

测试: MongoDB-游乐场


推荐阅读