$ max评估复合键

时间:2013-04-03 04:35:58

标签: mongodb aggregation-framework

聚合框架的$max运算符如何评估复合键。例如:

{
  $project: { 
    user: 1, 
    record: { date: "$upload_date", comment: 1, some_integer: 1 }
  }
},
{
  $group: {
    _id: "$user",
    latest: { $max : "$record" }
  }
}

它会在datecommentsome_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}}
  )

日志可以使用相同的名称tagcase_id,在分组两次后,我需要每个upload_date的结果只有tag的最新日志。< / p>

修改

我的预期结果如下:

  {
    '_id':'TAG-XYZ',
    'total':'1'
    'passing':'1'
    'failing':'0'
  }

每个计数对应于给定案例的最新日志。

2 个答案:

答案 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" }
    }}
])