Mongodb $ cond在聚合框架中

sc2*_*c28 3 mongodb

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

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"
Run Code Online (Sandbox Code Playgroud)

}

这是我正在尝试编写的聚合查询,我想要做的事情(请参阅注释掉的部分),是为了创建"原因/错误"代码的每个ipAddr的分组字段,但仅当原因代码开头时一个特定的字母,只在一次添加代码,我尝试了以下内容:

 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"} } 
   }
]);
Run Code Online (Sandbox Code Playgroud)

一切正常,不包括注释掉的'errorCodes'行.我试图创建的逻辑是:"添加errorCodes设置结果的值.因为它以A,B,S或N开头,否则没有任何东西可以添加".

对于上面的记录,errorCodes集包含:
... errorCodes:[S1002,A1001],...

Asy*_*sky 5

$group不能采用条件表达式,这就是为什么该行不起作用的原因.$project是您可以根据$cond特定表达式(以及其他内容)转换原始文档的阶段.

在可以之前,您需要在聚合管道中执行两个步骤$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"}
   }
]);
Run Code Online (Sandbox Code Playgroud)

如果你只想计算具有匹配错误代码的尝试,那么你可以用一个$group- 你需要这样做$unwind,$match并且$group.您可以像使用$ project $cond一样使用$ project ,但是您的errorCodes数组将包含一个空字符串条目以及所有正确的错误代码.