在Moongose中排序后,将$ lookup结果限制为1个文档

时间:2018-07-23 20:26:50

标签: mongodb mongoose aggregation-framework

我的租借模式:

$ cat tst.awk
{
    split($0,flds,FS,seps)
    flds[9] = "0.00"
    out = seps[0]
    for (i=1; i<=NF; i++) {
        out = out flds[i] seps[i]
    }
    print out
}

$ awk -f tst.awk file
ATOM      1  N   GLN     1      68.560  76.330  53.810  0.00  0.00
ATOM      2  H1  GLN     1      68.030  75.660  54.340  0.00  0.00
ATOM      3  H2  GLN     1      67.890  76.960  53.390  0.00  0.00
ATOM      4  H3  GLN     1      69.090  76.880  54.480  0.00  0.00
ATOM      5  CA  GLN     1      69.370  75.700  52.760  0.00  0.00
ATOM      6  HA  GLN     1      70.400  76.070  52.820  0.00  0.00
ATOM      7  CB  GLN     1      69.490  74.180  52.870  0.00  0.00
ATOM      8  HB2 GLN     1      69.650  73.790  53.880  0.00  0.00
ATOM      9  HB3 GLN     1      68.520  73.740  52.650  0.00  0.00
ATOM     10  CG  GLN     1      70.560  73.570  51.970  0.00  0.00

我的阅读模式:

var rentals = [{
    deviceId: 1,
    start_date: ISODate("2018-05-10T10:11:23.143Z") ,
    end_date: ISODate("2018-07-11T12:19:53.143Z")
},{
...
}]

我需要使用$ lookup将两个集合与读数一起加入,但是对于每个租借(deviceId),我只需要获取一个读数,即具有较高时间戳(最新)的读数。数据库中每个租金都有N个读数。

我的方法:

[{
    deviceId: 1,
    timestamp: ISODate("2018-05-11T10:11:23.143Z"),
    data: 'wathever'
},{
    deviceId: 2,
    timestamp: ISODate("2018-03-10T00:00:00.000Z"),
    data: 'wathever'
},{
    deviceId: 2,
    timestamp: ISODate("2018-05-18T00:00:00.000Z"),
    data: 'wathever'
},{
...
}]

我遇到错误:

Rental.aggregate([
      { "$match": { 
            clientId : ObjectId(req.params.clientId)
      }},    
      {  
          $lookup:{  
             from:"readings",
             localField:"deviceId",
             foreignField:"deviceId",
             let: { timestamp: "$timestamp"},
             pipeline: [
                 { $sort: { "$$timestamp": -1}},
                 { $limit : 1 },
             ],
             as:"lastReading"
          }
       },
       { $unwind: "$lastReading" },


    ], function(err, result) {
        console.log(result);
});

读数模式中的时间字段为日期类型。 肯定有些事情我做得不对...

1 个答案:

答案 0 :(得分:1)

您可以使用下面的聚合来后期处理联接的数据。

$lookup根据设备ID获取所有读数,然后按$unwind / $sort对以秒为单位的时间戳对读数进行排序。

$group(位于_id上)以收集每次租赁的最新读数。

类似

Rental.aggregate([
  {"$match":{"clientId":ObjectId(req.params.clientId)}},
  {"$lookup":{
    "from":"readings",
    "localField":"deviceId",
    "foreignField":"deviceId",
    "as":"readings"
  }},
  {"$unwind":"$readings"},
  {"$sort":{"readings.timestamp":-1}},
  {"$group":{"_id":"$_id","lastReading":{"$first":"$readings"}}}
])