按字段分组并在最大日期聚合

pag*_*off 1 mongodb aggregation-framework

我有mongo类型的文件-

{
    "_id" : ObjectId("77f02ee61df85c423b6a4e79"),
    "client" : "1"
    "type" : "type1",
    "hierarchy" : "hier1",
    "creationDate" : ISODate("2015-09-09T13:06:44Z"),
    "model" : "m1"
},
{
    "_id" : ObjectId("77f02ee61df85c423b6a4e80"),
    "client" : "1"
    "type" : "type1",
    "hierarchy" : "hier1",
    "creationDate" : ISODate("2015-09-10T14:06:44Z"),
    "model" : "m2"
},
{
    "_id" : ObjectId("77f02ee61df85c423b6a4e81"),
    "client" : "1"
    "type" : "type1",
    "hierarchy" : "hier2",
    "creationDate" : ISODate("2015-09-10T13:06:44Z"),
    "model" : "m3"
},
{
    "_id" : ObjectId("77f02ee61df85c423b6a4e82"),
    "client" : "2"
    "type" : "type2",
    "hierarchy" : "hier2",
    "creationDate" : ISODate("2015-09-10T14:06:44Z"),
    "model" : "m4"
}
Run Code Online (Sandbox Code Playgroud)

我想回答查询 - 对于给定的client,获取creationDate每个typehierarchy组合(类型+层次结构)的所有最新(按)文档。

例如。上述数据集的输出client = 1看起来像

 {
    "_id" : ObjectId("77f02ee61df85c423b6a4e80"),
    "client" : "1"
    "type" : "type1",
    "hierarchy" : "hier1",
    "creationDate" : ISODate("2015-09-10T14:06:44Z"),
    "model" : "m2"
},
{
    "_id" : ObjectId("77f02ee61df85c423b6a4e81"),
    "client" : "1"
    "type" : "type1",
    "hierarchy" : "hier2",
    "creationDate" : ISODate("2015-09-10T13:06:44Z"),
    "model" : "m3"
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用给定的流/管道创建查询-

  1. Match文档 where client = 1$match内部聚合)。
  2. group通过“列表”和“层次结构”($group内部聚合)。
  3. 我想按最新creationDate字段聚合上一步中的文档组。而不是应用聚合函数($sum, $avg etc),我实际上想要creationDate每个组中具有最新字段的文档

但是我被困在流程中的第 3 点。我不知道如何与同一聚集文件type,并hierarchy选择了一个与最晚日期(creationDate)在单一每种类型和层次mongo的查询。

Bat*_*eam 10

使用舞台$first内的操作符$group$project如果有必要,然后包括一个阶段。使用该$$ROOT变量将整个字段保留在名为 的变量下record

示例代码:

db.t.aggregate([
{$match:{"client":"1"}},
{$sort:{"creationDate":-1}},
{$group:{"_id":{"type":"$type",
                "hierarchy":"$hierarchy"},
          "record":{$first:"$$ROOT"}}}
])
Run Code Online (Sandbox Code Playgroud)

添加$project像下面这样的阶段,以获取顶层的文档字段,这不是必需的,可以在客户端轻松处理。

{$project:{"_id":0,"client":"$record.client","model":"$record.model",..}}
Run Code Online (Sandbox Code Playgroud)