2013-01-11 58 views
2

我有一个文档的集合,如下所示: {

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" 

}

这里是聚集查询我试着写,我想do(请参见注释掉的部分)是为每个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"} } 
    } 
]); 

一切正常,不包括注释掉的'errorCodes'一行。我试图创建的逻辑是: “添加errorCodes设置结果的值。原因码如果它以A,B,S或N开头,否则不需要添加任何内容”。

为了记录上述情况,ErrorCode的设置包含:
... ErrorCode的:S1002,A1001], ...

回答

4

$group为什么不能把条件表达式,这是该行不管用。 $project是您可以基于$cond itional表达式(等等)转换原始文档的阶段。

你之前,你可以$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,但是那么您的errorCodes数组将具有空字符串条目以及所有正确的错误代码。

0

由于蒙戈2.4,$正则表达式可用于模式匹配,而不是作为一个表达式返回一个布尔值,它是什么了$ COND需要

然后,您可以使用一个$匹配运营商使用在$正则表达式关键字:

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" 
       ] 
      } 
     } 
    } 
} 
]