MongoDB聚合$ max并从$ max的文档中选择

时间:2014-06-06 17:50:33

标签: mongodb mongodb-query aggregation-framework

我希望聚合查找一个字段的最大值,同时包括选择最大值的文档中的其他字段。

我可能会犯这个错误,但这是一个例子:

示例数据:

{
  utime: 1,
  device: "host1",
  latest_events: ['that']
},{
  utime: 2,
  device: "host1",
  latest_events: ['this', 'that']
},{
  utime: 3,
  device: "host1",
  latest_events: ['that', 'something']
},{
  utime: 1,
  device: "host2",
  latest_events: ['this', 'that']
},{
  utime: 2,
  device: "host2",
  latest_events: ['that']
},{
  utime: 3,
  device: "host2",
  latest_events: ['this', 'the_other']
}

这是我期望的结果:

[
  {
    _id: 'host1',
    utime: 3,
    latest_events: ['that', 'something']
  },{
    _id: 'host2',
    utime: 3,
    latest_events: ['this', 'the_other']
  }
]

所以这是我到目前为止最接近的猜测:

db.data.aggregate([
  {
    $group: {
      _id: '$device',
     utime: {'$max': '$utime'},
     latest_events: {/* I want to select the latest_events based on the max utime*/}
    }
  }
]);

这可以概括为“我想为每个设备提供最新的latest_events”。

我一直试图弄清楚如何通过多个聚合阶段或使用项目或其他方式来实现这一目标,但到目前为止,我唯一可行的解​​决方案是使用多个查询。

1 个答案:

答案 0 :(得分:0)

你基本上说的很接近,但是你似乎错过了$last运算符的文档,这些运算符会像这样使用:

db.data.aggregate([
    // Sort in host and utime order
    { "$sort": { "host": 1, "utime": 1 } },

    // Group on the "last" item on the boundary
    { "$group": {
        "_id": "$device",
        "utime": { "$last": "$utime" },
        "latest_events": { "$last": "$latest_events" }
    }}
])

您基本上$sort按照您需要的顺序,然后在$last中的$group字段中使用$sort作为" last"从您已完成的排序顺序在分组边界上发生的项目。

产生:

{ "_id" : "host2", "utime" : 3, "latest_events" : [ "this", "the_other" ] }
{ "_id" : "host1", "utime" : 3, "latest_events" : [ "that", "something" ] }

如果你想要"主持人&#34>,你可以选择在最后添加一个{{3}}。按顺序排列。