在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
相关产品推荐
相关产品推荐

