我有一个包含如下文档的集合: {
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, '原因/错误'代码,但仅当原因代码以特定字母开头,并且只添加一次代码时,我尝试了以下内容:
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开头,否则没有任何东西可以添加”。
对于上面的记录,错误代码集应该包含:
...
errorCodes:[S1002,A1001],
...
答案 0 :(得分: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"}
}
]);
如果您只想计算具有匹配错误代码的尝试,那么您可以使用单个$group
来执行此操作 - 您需要执行$unwind
,$match
和{{1 }}。您可以使用带有$group
的$ project,但随后您的errorCodes数组将包含一个空字符串条目以及所有正确的错误代码。
答案 1 :(得分: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"
]
}
}
}
}
]