在所有文档中查找数组中的最新条目

时间:2015-11-08 17:37:35

标签: mongodb

我有多个文档,其中包含带有对象的数组。如何找到阵列中的最新条目,但是在所有文档中。举个例子:

{
  doctitle: “some title”,
  conditions: [
    {
      createdAt: ISODate("2014-12-21T13:59:26Z"),
      title: “some title 1”
    }, 
    {
      createdAt: ISODate("2014-12-22T13:59:26Z"),
      title: “some title 2”
    }
  ]
},
{
  doctitle: “other title”,
  conditions: [
    {
      createdAt: ISODate("2014-12-20T13:59:26Z"),
      title: “some title 3”
    }, 
    {
      createdAt: ISODate("2014-12-23T13:59:26Z"),
      title: “some title 4”
    }
  ]
}

我想找到最新的3个条件。它应该只输出docTitle和找到的一个条件。

{
  docTitle: "other title" ,
  condition: [ 
      {
      createdAt: ISODate("2014-12-23T13:59:26Z"),
      title: “some title 4”
     }
  ]
},
{
  docTitle: "some title" ,
  condition: [ 
      {
      createdAt: ISODate("2014-12-22T13:59:26Z"),
      title: “some title 2”
     }
  ]
},
{
  docTitle: "some title" ,
  condition: [ 
      {
      createdAt: ISODate("2014-12-21T13:59:26Z"),
      title: “some title 1”
     }
  ]
}

1 个答案:

答案 0 :(得分:2)

使用以下聚合管道执行初始 $unwind 运算符,以通过条件数组字段对文档进行“非规范化”,以便每个输出文档都使用元素值替换该数组。对于每个输入文档,输出n个文档,其中n是数组元素的数量,对于空数组,可以为零。

下一个管道步骤使用 $sort 运算符通过嵌入式createdAt字段重新排序文档,这是下一个管道步骤所必需的,即 $limit $group 运营商。

由于您只需要按createdAt字段降序排序的前三个文档, $limit 通过将未修改的前3个文档传递到管道来为您做到这一点指定的限制是3。

前面的 $group 管道阶段是通过使用 $first 和修改条件数组来获取“doctitle”字段的位置当您按createdAt字段对文档进行分组时, $push 累加器运算符。

最后一个管道步骤 $project 会从先前的管道流中删除_id字段,因此最终的管道将如下所示:

db.collection.aggregate([
    { "$unwind": "$conditions" },
    { "$sort": { "conditions.createdAt": -1 }  },
    { "$limit": 3 },
    {
        "$group": {
            "_id": "$conditions.createdAt",
            "doctitle" : { "$first": "$doctitle" },
            "conditions": { "$push": "$conditions" }
        }
    },
    {
        "$project": {
            "_id": 0, "doctitle": 1, "conditions": 1
        }
    }
])

示例输出:

/* 0 */
{
    "result" : [ 
        {
            "doctitle" : "some title",
            "conditions" : [ 
                {
                    "createdAt" : ISODate("2014-12-21T13:59:26.000Z"),
                    "title" : "some title 1"
                }
            ]
        }, 
        {
            "doctitle" : "some title",
            "conditions" : [ 
                {
                    "createdAt" : ISODate("2014-12-22T13:59:26.000Z"),
                    "title" : "some title 2"
                }
            ]
        }, 
        {
            "doctitle" : "other title",
            "conditions" : [ 
                {
                    "createdAt" : ISODate("2014-12-23T13:59:26.000Z"),
                    "title" : "some title 4"
                }
            ]
        }
    ],
    "ok" : 1
}