将主集合与事务状态集合匹配

时间:2019-02-19 16:14:37

标签: mongodb mongoose mongodb-query aggregation-framework

我的问题比较具体,所以我将首先尝试解释我的设置。

我有一个名为clients的集合,它是所有客户端的主列表。它的模型是:

{
    id: String,
    organizationId: Number,
    networkId: String,
    deviceSerial: String,
}

(不相关的属性已删除)

我还有一个名为clienttransactions的集合,该集合列出了客户端何时联机或脱机。因此,每当客户端上线时,都会添加一条记录,表示该记录已上线(online: true),反之亦然,当客户端下线时(online: false)。该模型如下所示:

{
    clientId: String,
    deviceSerial: String,
    networkId: String,
    organizationId: Number,
    ts: Number,
    online: Boolean
}

ts是Unix时间戳,以秒为单位。另外,如果您想知道为什么我在每条记录上都需要所有这些外键,那是因为从我那里获取这些数据的API的工作方式。因此,请忽略它。

问题:

给定deviceSerialnetworkIdorganizationId,我想查找在给定时间范围(给定的开始时间和结束时间)之间在任何时间在线的所有客户端纪元秒)。

可能的情况:有时候,客户可能会在给定的开始时间之前上线,然后一直保持在线状态,直到给定的结束时间之后。在这种情况下,在该时间范围内将没有交易记录,但是客户仍应被视为在线。

解决这种情况是我最大的麻烦,因为我不能只是在时间范围内搜索在线交易。如果在该时间段内没有客户的交易,那么我需要在时间范围之外进行搜索,以查看该客户开始时间之前的最后一笔交易是否是在线交易。

我对聚合管道还不很精通,所以据我所知:

const startTime = 1550601742;
const endTime = 1550599341;

ClientTransaction.aggregation([
  {
    $match: {
      organizationId: 600381,
      networkId: 'N_651896046061895525',
      deviceSerial: 'Q2MN-3CUN-6GQM',
      ts: {$lt: endTime}
    }
  },
  {
    $group: {
      _id: '$clientId',
      lastStatus: {
        $max: '$ts'
      },
      online: {
        $last: '$online'
      }
    }
  }
]);

我认为我已经中途了。它会在结束时间之前找到唯一客户的所有交易,但会在检查客户在该时间段内是否真正在线之前停止。

1 个答案:

答案 0 :(得分:0)

您正在寻找最近活动是开始时间之前的在线活动或在开始时间和结束时间之间具有在线/离线活动的所有客户。

所以类似的东西应该起作用

ClientTransaction.aggregation([
  { $match: { 
      organizationId: 600381, 
      networkId: 'N_651896046061895525',
      deviceSerial: 'Q2MN-3CUN-6GQM',
      ts: {$lte: endTime}
    }
  },
  { $sort:{"clentId":1, "ts":-1 } },
  { $group: {
      _id: '$clientId',
      latest: {
        $first: '$$ROOT'
      }
  }},
  { $match:{
     $or:[
       {"latest.online":true,"latest.ts":{$lt:startTime}},
       {"latest.ts":{$gte:startTime, $lte:endTime}}
     ]
  }}
]);