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

在Golang项目中实现MongoDB聚合regexMatch逻辑的语法求助

问题描述

我在Studio3T里写了一段能正常运行的MongoDB聚合查询,现在要迁移到正在开发的Golang项目里。但我对bson.A、bson.D、bson.M这些类型的适用场景不太清楚,而且MongoDB查询和Golang代码的语法、括号结构转换总是出错,急需语法上的帮助。

现有MongoDB文档数据

{
    "errorMsg" : " Authorization is a duplicate; Tracking Number(s): AAAA-BBBB"
}
{
    "errorMsg" : " Authorization is a duplicate; Tracking Number(s): CCCC-DDDD"
}
{
    "errorMsg" : " Authorization is a duplicate of IP123456789; Tracking Number(s): EEEE-FFFF"
}
{
    "errorMsg" : " authorizationNbr [GGGG-HHHH] INVALID: unknown origin"
}
{
    "errorMsg" : " authorizationNbr [IIII-JJJJ] INVALID: unknown origin"
}
{
    "errorMsg" : " Unable to update, apologies . Please resubmit: AUTH_CRUD_API: %!s(<nil>)"
}
{
    "errorMsg" : " Unable to update, apologies . Please resubmit"
}

期望处理结果

{
    "errorMsg" : " Authorization is a duplicate"
}
{
    "errorMsg" : " Authorization is a duplicate"
}
{
    "errorMsg" : " Authorization is a duplicate"
}
{
    "errorMsg" : " authorizationNbr"
}
{
    "errorMsg" : " authorizationNbr"
}
{
    "errorMsg" : " Unable to update"
}
{
    "errorMsg" : " Unable to update"
}

Studio3T中的addFields阶段查询

addFields
{
    "errorMsg": { "$cond": [{ "$regexMatch": {"input": "$errorMsg", "regex": "Authorization is a duplicate"}}, "Authorization is a duplicate", 
        {"$cond": [{ "$regexMatch": {"input": "$errorMsg", "regex": "authorizationNbr"}}, "authorizationNbr", 
            {"$cond" : [{"$regexMatch" : {"input" : "$errorMsg", "regex" : "[Uu]nable to update, apologies"}}, "Unable to update", "$errorMsg"]}]}]}
}

我写的Golang代码(需要修正)

addFields := bson.D{{"$addFields", bson.D{
        {"errorMsg", bson.D{{"$cond", bson.A{bson.D{{"$regexMatch", bson.A{"input": "$errorMsg", "regex": "Authorization is a duplicate"}}}, "Authorization is a duplicate",
            {"$cond", bson.A{bson.D{{"$regexMatch", bson.A{"input": "$errorMsg", "regex": "authorizationNbr"}}}, "authorizationNbr",
                {"$cond", bson.A{bson.D{{"$regexMatch", bson.A{"input": "$errorMsg", "regex": "[Uu]nable to update, apologies"}}}, "Unable to update", "$errorMsg"}}}}
            }}}},
    }}}

解决方案

先明确bson类型的使用场景

  • bson.D:有序键值对列表,适合需要严格保持字段顺序的场景(比如聚合阶段定义、$cond的条件判断结构)
  • bson.A:数组类型,对应MongoDB中的数组(比如$cond的参数列表,因为$cond是按[条件, 满足值, 不满足值]的顺序传参)
  • bson.M:无序map结构,适合不需要顺序的普通文档,写法更简洁

修正后的Golang代码

你的代码核心错误是把$regexMatch的参数写成了bson.A,但$regexMatch需要的是键值对文档,不是数组。修正后的代码如下:

addFields := bson.D{
    {"$addFields", bson.D{
        {"errorMsg", bson.D{
            {"$cond", bson.A{
                // 第一个$cond:匹配Authorization is a duplicate
                bson.D{
                    {"$regexMatch", bson.D{
                        {"input", "$errorMsg"},
                        {"regex", "Authorization is a duplicate"},
                    }},
                },
                "Authorization is a duplicate",
                // 嵌套第二个$cond
                bson.D{
                    {"$cond", bson.A{
                        bson.D{
                            {"$regexMatch", bson.D{
                                {"input", "$errorMsg"},
                                {"regex", "authorizationNbr"},
                            }},
                        },
                        "authorizationNbr",
                        // 嵌套第三个$cond
                        bson.D{
                            {"$cond", bson.A{
                                bson.D{
                                    {"$regexMatch", bson.D{
                                        {"input", "$errorMsg"},
                                        {"regex", "[Uu]nable to update, apologies"},
                                    }},
                                },
                                "Unable to update",
                                "$errorMsg",
                            }},
                        },
                    }},
                },
            }},
        }},
    }},
}

简化写法(用bson.M更易读)

如果不需要严格字段顺序,用bson.M可以大幅简化代码:

addFields := bson.D{
    {"$addFields", bson.M{
        "errorMsg": bson.M{
            "$cond": bson.A{
                bson.M{"$regexMatch": bson.M{"input": "$errorMsg", "regex": "Authorization is a duplicate"}},
                "Authorization is a duplicate",
                bson.M{
                    "$cond": bson.A{
                        bson.M{"$regexMatch": bson.M{"input": "$errorMsg", "regex": "authorizationNbr"}},
                        "authorizationNbr",
                        bson.M{
                            "$cond": bson.A{
                                bson.M{"$regexMatch": bson.M{"input": "$errorMsg", "regex": "[Uu]nable to update, apologies"}},
                                "Unable to update",
                                "$errorMsg",
                            },
                        },
                    },
                },
            },
        },
    }},
}

错误点说明

你原来的代码中,$regexMatch的参数用了bson.A{"input": "$errorMsg", "regex": "..."},这是错误的——$regexMatch需要的是键值对文档(对应MongoDB的{"input": ..., "regex": ...}),而bson.A仅用于表示MongoDB中的数组类型(比如$cond的三个参数组成的数组)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:23:22