根据 mongoDB 中的字段获取最后一条记录

Fetch last record based on field in mongoDB

我是 mongo 的新手。我正在尝试根据特定字段获取最后的记录。在SQLselect * from powerandlevel group by deviceId order by desc limit 1。因此,在这个基于 deviceId 的 SQL 查询中,我可以获得每个 deviceId 的最后一条记录。我想在 mongodb

中做同样的事情
[{
_id: "ObjectId(6246ab45e95eac6c85726cfc)"
imageName: "IMG_123456.jpg"
eventTime: "2022-04-01T07:35:30.615Z"
deviceId: "48701ED21819"
},
{
_id: "ObjectId(6246ab45e95eac6c85726cfc)"
imageName: "IMG_123456.jpg"
eventTime: "2022-04-01T07:38:10.543Z"
deviceId: "58701ED21819"
},
{
_id: "ObjectId(6246ab45e95eac6c85726cfc)"
imageName: "IMG_123456.jpg"
eventTime: "2022-04-01T08:05:50.865Z"
deviceId: "48701ED21819"
}]

我正在使用这个查询 db.imageEvent.aggregate([{ "$group" : {"_id" : { "deviceId" : "$deviceId"}}}, {$sort: {eventTime: 1}}, { $limit : 1 }])

结果

[{ "_id" : { "deviceId" : "58701ED21819" } },
{ "_id" : { "deviceId" : "48701ED21819" } }]

期待这样的结果

[{
_id: "ObjectId(6246ab45e95eac6c85726cfc)"
imageName: "IMG_123456.jpg"
eventTime: "2022-04-01T07:38:10.543Z"
deviceId: "58701ED21819"
},
{
_id: "ObjectId(6246ab45e95eac6c85726cfc)"
imageName: "IMG_123456.jpg"
eventTime: "2022-04-01T08:05:50.865Z"
deviceId: "48701ED21819"
}]
  1. $sort - 按 eventTime DESC.
  2. 排序
  3. $group - 按 deviceId 分组并通过 $first.
  4. 将第一个文档放入 data 字段
  5. $replaceRoot - 将输入文档替换为 data
db.imageEvent.aggregate([
  {
    $sort: {
      eventTime: -1
    }
  },
  {
    "$group": {
      "_id": {
        "deviceId": "$deviceId"
      },
      data: {
        $first: "$$ROOT"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": "$data"
    }
  }
])

Sample Mongo Playground

如果您不需要每个结果的ObjectId,只需要常用值和最新日期,您可以通过以下方式简化它:

db.imageEvent.aggregate([
  {
    $group: {
      _id: "$deviceId",
      imageName: {$first: "$imageName"},
      eventTime: {$max: "$eventTime"},
      deviceId: {$first: "$deviceId"},
    }
  }
])

正如您在 playground 上看到的那样 $first 对于组中相同的值很方便。 $max 会给你最新的日期。

这将阻止您对整个集合进行排序以及在查询期间创建大型文档,因为文档有大小写限制。