MongoDB聚合最后一项匹配条件

时间:2017-02-03 07:51:15

标签: mongodb mongodb-query aggregation-framework

我想获得符合特定条件的列的最后一个值。如果我使用$last$cond,它几​​乎总会给我$cond的第三个参数。

例如:我有以下记录

{uid:1,subject:"Maths",name:"Assignment 1",s_date:"2017-01-15 00:00:00"}
{uid:1,subject:"Maths",name:"Assignment 2",s_date:"2017-01-17 00:00:00"}
{uid:2,subject:"Maths",name:"Assignment 1",s_date:"2017-01-16 00:00:00"}
{uid:1,subject:"Science",name:"Assignment 1",s_date:"2017-01-11 00:00:00"}

我想对这些项目进行分组,以找出每个主题的最后一次分配的提交日期。我试图做的是

collection.aggregate(
    {
        $group: {
        _id: '$uid',
        science: { 
            $last: {
                $cond: [
                    { $eq: ['$subject','Science'] },
                    '$u_date',
                    null
                ]
            }
        }
    }
)

在这种情况下,如果用户的最后一条记录没有主题为“科学”,我将始终得到null作为输出。

(我知道这可以通过分组_id:{'uid':'$uid','subject':'$subject'}.来完成。这是一个假设的例子。我的实际记录集有点复杂。

请理解我不想要

中的最终输出
{_id:{uid:1,subject:"Science"},'s_date':'2017-01-11 00:00:00'} 

格式,但在

{_id:1,science:'2017-01-11 00:00:00',maths:'2017-01-14 00:00:00'} 

格式)。

请以另一种方式帮助我。我想过使用$filter$setDifference但是这会使它变得更复杂,因为记录集很大并且查询是由系统动态生成的。

1 个答案:

答案 0 :(得分:0)

您可以使用$ group两次。

collection.aggregate([
  { $sort: { s_date: -1 } },
  { $group: {
    _id: { uid: '$uid', subject: '$subject' },
    s_date: { $last: '$s_date' },
  } },
  { $group: {
    _id: '$_id.uid',
    s_dates: { $push: { subject: "$_id.subject", s_date: "$s_date" } },
  } },
])

结果:

{
  _id: 1,
  s_dates: [
    { subject: 'Maths', s_date: '2017-01-17 00:00:00' },
    { subject: 'Science', s_date: '2017-01-11 00:00:00' },
  ],
}
{
  _id: 2,
  s_dates: [
    { subject: 'Maths', s_date: '2017-01-16 00:00:00' },
  ],
}