聚合框架的$max
运算符如何评估复合键。例如:
{
$project: {
user: 1,
record: { date: "$upload_date", comment: 1, some_integer: 1 }
}
},
{
$group: {
_id: "$user",
latest: { $max : "$record" }
}
}
它会在date
,comment
或some_integer
之后达到最大值吗?我只是假设它将获得最新的date
。如果错了,date
找到最大值的正确方法是什么?
修改
从我到目前为止所尝试的,最新记录由第一个键决定。这是正确的行为吗?
修改
为了了解我的用例,我有以下文档:
> db.logs.findOne()
{
'id': ObjectId("50ad8d451d41c8fc58000003")
'name': 'Sample Log 1',
'uploaded_at': ISODate("2013-03-14T01:00:00+01:00"),
'case_id': '50ad8d451d41c8fc58000099',
'result': 'passing'
'tag': ['TAG-XYZ']
}
我有以下聚合:
db.test_case_logs.aggregate(
{$project: {tag:'$tag', case:'$case_id',
latest: {upload_date:1, date:'$upload_date', result:'$result',
passing : { $cond : [ { $eq : ["$result","passing"] }, 1, 0 ] },
failing : { $cond : [ { $eq : ["$result","failing"] }, 1, 0 ] }}
}},
{$unwind: '$tag'},
{$group: {_id:{tag:'$tag',case:'$case'}, latest:{$max:'$latest'}}},
{$group: {_id:'$_id.tag',total:{$sum:1}, passing:{$sum:{$latest.passing}},
failing:{$sum:{$latest.failing}, date:{$max:{$latest.upload_date}}}
},
{'$sort': {'date':-1}}
)
日志可以使用相同的名称tag
和case_id
,在分组两次后,我需要每个upload_date
的结果只有tag
的最新日志。< / p>
修改
我的预期结果如下:
{
'_id':'TAG-XYZ',
'total':'1'
'passing':'1'
'failing':'0'
}
每个计数对应于给定案例的最新日志。
答案 0 :(得分:0)
根据$max
documentation,此运算符
返回此组选择的所有文档中字段的所有值中的最高值。
您可以按{$ max:“$ record.date”}
指定日期的最大操作数聚合操作如下:
db.collection.aggregate ([
{ $project: {
user: 1,
record: { date: "$upload_date", comment: 1, some_integer: 1 }
}},
{ $group: {
_id: "$user",
latest: { $max : "$record.date" }
}}
])
答案 1 :(得分:0)
对于您的情况,您可以使用$sort
运算符按$ uploaded_at字段对所有日志进行排序,并按标记和case_id对排序后的结果进行分组,然后使用$first
运算符来获取每组的第一项。
db.logs.aggregate([
// Rename the fields and process the result field
{ $project : {
tag : 1,
case : "$case_id",
date : "$uploaded_at",
result : {
passing : { $cond : [ { $eq : ["$result","passing"] }, 1, 0 ] },
failing : { $cond : [ { $eq : ["$result","failing"] }, 1, 0 ] }}
}},
// Create a stream of documents from the tag array
{ $unwind : "$tag" },
// Sort by uploaded date descending
{ $sort : { date : -1 }},
// Group the documents by tag and case_id, and use $first operation to get the latest log for each group
{ $group : {
_id : { tag : "$tag", case : "$case" },
latest : { $first : "$result" },
}},
// Group the document by tag, and caculate the total/pass/fail results
{ $group : {
_id : "$_id.tag",
total : { $sum : 1 },
passing : { $sum : "$latest.passing" },
failing : { $sum : "$latest.failing" }
}}
])