我的问题是相当具体的,所以我将尝试首先解释我的设置。
我有一个名为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的工作方式。所以忽略它就好了。
问题:
给定deviceSerial、networkId和organizationId,我希望找到在给定时间范围(给定开始时间和结束时间,以纪元秒为单位)之间的任意时间点处于在线状态的所有客户端。
可能的边缘情况:有时客户端在给定的开始时间之前在线,并保持在线直到给定的结束时间之后。在这种情况下,在时间范围内将没有事务记录,但客户端仍应被视为在线。
对这种情况的解释是我遇到的最大的麻烦,因为我不能简单地搜索时间框架之间的在线交易。如果在时间范围内没有客户端的事务,那么我需要在时间范围外进行搜索,以查看在该客户端的开始时间之前进行的最后一次事务是否是在线事务。
我对聚合管道还不是很精通,所以这就是我所了解到的:
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'
}
}
}
]);我想我已经做了一半了。它在结束时间之前查找唯一客户端的所有事务,但在检查客户端在该时间范围内是否真正在线的过程之前停止。
发布于 2019-02-22 06:42:57
您正在查找其最新活动是开始时间之前的联机活动或在开始时间和结束时间之间具有联机/脱机活动的所有客户端。
所以像这样的东西应该是有效的
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}}
]
}}
]);https://stackoverflow.com/questions/54770610
复制相似问题