You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MongoDB聚合根据数组字段存在性添加新数组字段

MongoDB聚合:仅为数组中存在指定字段的元素添加新字段

问题场景

现有collectionA中的文档结构如下:

{
        "_id" : ObjectId("641893db137e63c5d6940f68"),
        "summaryId" : 20,
        "actions" : [
                {
                        "action" : "Action A",
                        "actionDate" : "2023-02-25 20:59:49"
                },
                {
                        "action" : "Action B",
                        "actionDate" : "2021-11-18 20:49:55",
                        "actorRoleId" : 5
                },
                {
                        "action" : "Action C",
                        "actionDate" : "2021-11-25 20:49:55",
                        "actorRoleId" : 4
                },
                {
                        "action" : "Action D",
                        "actionDate" : "2023-02-25 20:49:55"
                }
        ]
}

需求是:仅为actions数组中包含actorRoleId字段的元素添加新字段actorUserId,使用聚合操作实现。

原代码存在问题:直接给整个actions数组的所有元素添加了actorUserId,不符合需求:

pipeline = [
    {
        "$match": {
            "actions.actorRoleId": {"$exists": True}
        }
    },
    {
        "$addFields": {
            "actions.actorUserId": "Testing"
        }
    },
    {
        "$project": {
            "summaryId": True,
            "actions": True
        }
    },
    {"$merge": "summary"},
]

db.collectionA.aggregate(pipeline)

正确解决方案

需要使用$map遍历数组元素,结合$cond条件判断和$mergeObjects合并字段,仅为符合条件的元素添加新字段:

pipeline = [
    {
        "$match": {
            "actions.actorRoleId": {"$exists": True}
        }
    },
    {
        "$addFields": {
            "actions": {
                "$map": {
                    "input": "$actions",
                    "as": "item",
                    "in": {
                        "$cond": {
                            "if": {"$exists": ["$$item.actorRoleId", True]},
                            "then": {"$mergeObjects": ["$$item", {"actorUserId": "Testing"}]},
                            "else": "$$item"
                        }
                    }
                }
            }
        }
    },
    {
        "$project": {
            "summaryId": True,
            "actions": True
        }
    },
    {"$merge": "summary"}  # 若要合并回原集合,可改为"collectionA"
]

db.collectionA.aggregate(pipeline)

代码说明

  1. $match阶段:过滤出actions数组中至少有一个元素包含actorRoleId的文档,避免处理无符合条件元素的文档,提升效率。
  2. $addFields阶段:
    • 使用$map遍历actions数组的每个元素(命名为$$item)。
    • 通过$cond判断当前元素是否存在actorRoleId字段:
      • 存在:用$mergeObjects将原元素和新字段actorUserId合并,生成新的元素对象。
      • 不存在:直接返回原元素,不做修改。
  3. $project阶段:保留需要的字段,可根据实际需求调整。
  4. $merge阶段:将聚合结果合并到指定集合,若要覆盖原文档,可添加whenMatched: "replace"等参数(默认行为是合并字段)。

内容的提问来源于stack exchange,提问作者wheeliea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:32:37