我的数据看起来像这样:
{
"timestamp": ISODate("2018-07-31T13:30:00Z"),
"mapId": "b312c970-ea39-436d-b930-47ce64ff910f",
"deviceId": "e272f2be-b398-4489-afa4-cb1a249406bf",
"_id": ObjectId(...)
}
我们假设它们是地图上的位置(被截断的数据)。
我想在MongoDB中执行以下语句。
查找任何设备在特定地图上花费的平均时间。如果两个连续的差值大于特定阈值,则设备将离开地图。
一个例子,我们假设只存在一张地图。请注意,我们对每个特定设备的平均时间不感兴趣,而对所有设备的平均时间感兴趣。 (因此,数据中只提到了时间戳记)
[
{ "timestamp": ISODate("2018-07-31T13:30:00Z") },
{ "timestamp": ISODate("2018-07-31T13:40:00Z") },
{ "timestamp": ISODate("2018-07-31T13:55:00Z") },
{ "timestamp": ISODate("2018-07-31T15:40:00Z") },
{ "timestamp": ISODate("2018-07-31T15:45:00Z") },
{ "timestamp": ISODate("2018-07-31T18:00:00Z") },
]
我们将定义离开设备的时差设置为15分钟。据此,我们将得到15 minutes
的平均花费时间。为什么会这样?
因此,我们有两个25 minutes, 5 minutes
的跨度。计算平均值:(25 + 5) minutes / 2 timespans = 15 minutes
使用普通JavaScript,我将执行以下操作(我不想讨论代码的质量-我知道它可以提高。:))
const threshold = 1000 * 60 * 15;
const timespans = [];
let previous = undefined;
let valuesWithinThreshold = [];
dataForOneDevice
.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1)
.forEach((position, index) => {
if (index === 0) {
valuesWithinThreshold.push(position);
}
if (previous) {
const range = Math.abs(previous.timestamp - position.timestamp);
if (range <= threshold) {
valuesWithinThreshold.push(position);
} else {
const first = valuesWithinThreshold[0];
const last = valuesWithinThreshold[valuesWithinThreshold.length - 1];
if (first && last && first !== last) {
timespans.push(last.timestamp - first.timestamp);
}
valuesWithinThreshold = [];
valuesWithinThreshold.push(position);
}
}
previous = position;
});
const sum = timespans.reduce((a, b) => a + b);
console.log('average', sum / timespans.length / 1000 / 60, 'minutes');
我的问题
最好, 菲利普