聚合框架中的Mongodb $cond

3
我可以帮助您进行翻译。以下是需要翻译的内容:

我有一个包含以下文档的集合:

{
ipAddr: '1.2.3.4',
"results" : [
             {
                     "Test" : "Sight",
                     "Score" : "FAIL",
                     "Reason" : "S1002"
             },
             {
                     "Test" : "Speed",
                     "Score" : "FAIL",
                     "Reason" : "85"
             },
             {
                     "Test" : "Sound",
                     "Score" : "FAIL",
                     "Reason" : "A1001"
             }
     ],
     "finalGrade" : "FAILED"

}

这是我正在尝试编写的聚合查询,我想要做的事情(见注释部分)是为每个ipAddr创建一个分组字段,其中包含'Reason / Error'代码,但仅当Reason代码以特定字母开头时,并且仅添加一次该代码。我尝试了以下代码:
 db.aggregate([
   {$group: 
        {  _id: "$ipAddr", 
         attempts: {$sum:1}, 
         results: {$push: "$finalGrade"},    
        // errorCodes: {$addToSet: {$cond: ["$results.Reason": /[A|B|S|N.*/, "$results.Reason", ""]}},                                                              
        finalResult: {$last: "$finalGrade"} } 
   }
]);

除了被注释掉的'errorCodes'行以外,一切正常。我尝试创建的逻辑是:“如果结果代码以A、B、S或N开头,则将错误代码集添加到结果原因代码的值中,否则无需添加”。对于上面的记录,errorCodes集合应该包含:[S1002, A1001]。
2个回答

5

$group 不能使用条件表达式,这就是为什么那行代码不起作用的原因。$project 是您可以根据条件表达式(以及其他内容)转换原始文档的阶段。

在您能够使用 $group之前,需要在聚合管道中执行两个步骤-首先,您需要$unwind 结果数组,接下来需要$match 过滤掉不关心的结果。

这样做只会简单地丢弃您不想要保留的错误代码结果,但是看起来您想计算所有错误代码的总故障次数,然后只将特定的错误代码添加到输出数组中?这并不是一种直接的方法,您需要在管道中进行两个$group$unwind通过。

类似于以下内容:

db.aggregate([
   {$unwind : "$results"},
   {$group:
        { _id: "$ipAddr",
          attempts: {$sum:1},
          results: {$push : "$results"},
          finalGrade: {$last : "$finalGrade" } 
        } 
   },
   {$unwind: "$results"},
   {$match: {"results.Reason":/yourMatchExpression/} },
   {$group: 
        {  _id: "$ipAddr", 
         attempts: {$last:"$attempts"},    
         errorCodes: {$addToSet: "$results.Reason"},                                                              
        finalResult: {$last: "$finalGrade"}
   }
]);

如果你只想计算具有匹配错误代码的尝试次数,那么可以使用一个单独的$group完成 - 你需要进行$unwind$match$group。你可以像之前一样使用$cond来使用$project,但是你的错误代码数组将会有一个空字符串条目以及所有正确的错误代码。

0

从Mongo 2.4开始,$regex可用于模式匹配,但不能作为返回布尔值的表达式,这是$cond所需的。

然后,您可以使用$match运算符来使用$regex关键字:

http://mongotry.herokuapp.com/#?bookmarkId=52fb39e207fc4c02006fcfed

[
{
    "$unwind": "$results"
},
{
    "$match": {
        "results.Reason": {
            "$regex": "[SA].*"
        }
    }
},
{
    "$group": {
        "_id": "$ipAddr",
        "attempts": {
            "$sum": 1
        },
        "results": {
            "$push": "$finalGrade"
        },
        "undefined": {
            "$last": "$finalGrade"
        },
        "errorCodes": {
            "$addToSet": "$results.Reason"
        }
    }
}
]

或者你可以使用$substr,因为你的模式匹配非常简单 http://mongotry.herokuapp.com/index.html#?bookmarkId=52fb47bc7f295802001baa38

[
{
    "$unwind": "$results"
},
{
    "$group": {
        "_id": "$ipAddr",
        "errorCodes": {
            "$addToSet": {
                "$cond": [
                    {
                        "$or": [
                            {
                                "$eq": [
                                    {
                                        "$substr": [
                                            "$results.Reason",
                                            0,
                                            1
                                        ]
                                    },
                                    "A"
                                ]
                            },
                            {
                                "$eq": [
                                    {
                                        "$substr": [
                                            "$results.Reason",
                                            0,
                                            1
                                        ]
                                    },
                                    "S"
                                ]
                            }
                        ]
                    },
                    "$results.Reason",
                    "null"
                ]
            }
        }
    }
}
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接