根据 Group Mongoose 查找最新记录

XPL*_*1ON 5 javascript mongoose mongodb node.js

我对 NoSQL 很陌生并且正在努力编写这个查询 我在 Node.js 上使用 Mongoose

我想要实现的是根据设备 ID 组获得一个最新结果。我用 SQL 写这个没有问题,但在 NoSQL 中很难做到。

这是模型设置

_id     DeviceID     Coordinate:{lat, long}
1       2            lat: 1, long: 2
2       3            lat: 2, long: 3
3       1            lat: 3, long: 3
4       3            lat: 5, long: 4
5       2            lat: 7, long: 5
6       2            lat: 9, long: 6
7       3            lat: 111, long: 7
8       2            lat: 113, long: 8
Run Code Online (Sandbox Code Playgroud)

我想要的输出是:

_id     DeviceID     Coordinate:{lat, long}
3       1            lat: 3, long: 3
7       3            lat: 111, long: 7
8       2            lat: 113, long: 8
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的,但我得到的结果是 undefined

注意:beginDayID,endDayID是 mongoose 的变量 ObjectId 代表一天开始和结束的 _id。

mongoose.model('GPSData').aggregate([
  {$match: {_id:{$gte: beginDayID, $lt: endDayID}}},
  {$unwind: "$Coordinates"},
  {$project: {DeviceID: '$DeviceID' }},
  {$group: { DeviceID: '$DeviceID', $lat: '$Coordinates.lat', $long: '$Coordinates.long'}}

  ], (e, data) => {
     console.error(e)
     console.log(data)
     if (e) return callback(e, null);
     return callback(null, data);
   })
Run Code Online (Sandbox Code Playgroud)

DAX*_*lic 5

我假设您有与此有些类似的文档

/* 1 */
{
    "_id" : 1,
    "DeviceID" : 1,
    "Coordinate" : {
        "lat" : 1,
        "long" : 2
    }
}

/* 2 */
{
    "_id" : 2,
    "DeviceID" : 2,
    "Coordinate" : {
        "lat" : 1,
        "long" : 6
    }
}
...
Run Code Online (Sandbox Code Playgroud)

那么像这样的聚合管道应该可以工作

mongoose.model('GPSData').aggregate([
  {
      $match: ... // your match filter criteria
  },
  {
      $sort: {
          _id: 1
      }
  },
  { 
      $group: { 
          _id: '$DeviceID',
          lastId: { $last: '$_id' },
          lat: { $last: '$Coordinate.lat' }, 
          long: { $last:'$Coordinate.long' }
      }
  },
  {
      $project: {
          _id: '$lastId',
          DeviceID: '$_id',
          lat: 1,
          long: 1
      }
  }
])
Run Code Online (Sandbox Code Playgroud)

输出文档的形状如下所示

/* 1 */
{
    "_id" : 1,
    "DeviceID" : 1,
    "Coordinate" : {
        "lat" : 1,
        "long" : 2
    }
}

/* 2 */
{
    "_id" : 2,
    "DeviceID" : 2,
    "Coordinate" : {
        "lat" : 1,
        "long" : 6
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意$sort在谈论保留“最后一个值”时必须指定顺序的附加阶段。如果您有其他要求,您可能需要指定其他排序