mongodb - 按 id 对 Mongo 文档进行分组,并按时间戳获取最新文档

假设我们在 mongodb 中存储了以下一组文档:

{ "fooId" : "1", "status" : "A", "timestamp" : ISODate("2016-01-01T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "1", "status" : "B", "timestamp" : ISODate("2016-01-02T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "1", "status" : "C", "timestamp" : ISODate("2016-01-03T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "2", "status" : "A", "timestamp" : ISODate("2016-01-01T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "2", "status" : "B", "timestamp" : ISODate("2016-01-02T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "3", "status" : "A", "timestamp" : ISODate("2016-01-01T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "3", "status" : "B", "timestamp" : ISODate("2016-01-02T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "3", "status" : "C", "timestamp" : ISODate("2016-01-03T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "3", "status" : "D", "timestamp" : ISODate("2016-01-04T00:00:00.000Z") "otherInfo" : "BAR", ... }

我想根据时间戳获取每个 fooId 的最新状态。因此,我的返回看起来像:

{ "fooId" : "1", "status" : "C", "timestamp" : ISODate("2016-01-03T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "2", "status" : "B", "timestamp" : ISODate("2016-01-02T00:00:00.000Z") "otherInfo" : "BAR", ... }
{ "fooId" : "3", "status" : "D", "timestamp" : ISODate("2016-01-04T00:00:00.000Z") "otherInfo" : "BAR", ... }

我一直在尝试通过使用 group 运算符的聚合来解决这个问题,但我想知道的部分是否有一种简单的方法可以从聚合中获取整个文档,所以它看起来就像我使用了查找查询一样?似乎您必须在分组时指定所有字段,如果文档可以包含我可能不知道的可选字段,这似乎不可扩展。我当前的查询如下所示:

db.collectionName.aggregate(
   [
     { $sort: { timestamp: 1 } },
     {
       $group:
         {
           _id: "$fooId",
           timestamp: { $last: "$timestamp" },
           status: { "$last": "$status" },
           otherInfo: { "$last": "$otherInfo" },
         }
     }
   ]
)

最佳答案

如果你正在做聚合,你需要做类似于 SQL 的操作,这意味着指定每列的聚合操作,你唯一的选择是使用 $$ROOT 操作符

db.test.aggregate(
   [
    { $sort: { timestamp: 1 } },
     {
       $group:
         {
           _id: "$fooId",
           timestamp: { $last: "$$ROOT" }
         }
     }
   ]
);

但这会稍微改变输出

{ "_id" : "1", "timestamp" : { "_id" : ObjectId("570e6be3e81c8b195818e7fa"), 
  "fooId" : "1", "status" : "A", "timestamp" :ISODate("2016-01-01T00:00:00Z"), 
  "otherInfo" : "BAR" } }

如果要返回原始文档格式,之后可能需要一个 $project 阶段

https://stackoverflow.com/questions/36603622/

相关文章:

python - 具有完整行对象的 Mongo Distinct Query

ruby-on-rails - 运行 Rails 应用程序时的 Mongo::Error::NoSe

javascript - Passport 没有保持持久的登录 session

java - MongoDb BSON 以 UTC 时间存储日期

mongodb - Docker-MongoDB 中的身份验证问题

java - 使用 Spring Data 按提取的日期、月份和年份聚合项目组

mongodb - Mongo在计算条件下排序

mongodb - 查询以匹配包含点的多边形

node.js - 关于 Mongoose 填充关系一个字符串字段

linux - PHP升级到7后,为什么不能使用mongodb驱动?