Mongodb querie获得时间序列的峰值
我有一个mongodb,里面有一些传感器数据。每次触发传感器时,该值增加1。有时传感器正在复位。现在我想把传感器数据的值加起来,得到timeseries的总值 我的数据如下所示:Mongodb querie获得时间序列的峰值,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一个mongodb,里面有一些传感器数据。每次触发传感器时,该值增加1。有时传感器正在复位。现在我想把传感器数据的值加起来,得到timeseries的总值 我的数据如下所示: { value: 10 timestamp: 1577836800 }, { value: 12 timestamp: 1577836810 }, { value: 17 <== PEAK timestamp: 1577836820 }, { value:
{
value: 10
timestamp: 1577836800
}, {
value: 12
timestamp: 1577836810
}, {
value: 17 <== PEAK
timestamp: 1577836820
}, {
value: 2
timestamp: 1577836830
}, {
value: 7
timestamp: 1577836840
}, {
value: 10 <== PEAK
timestamp: 1577836850
},{
value: 1
timestamp: 1577836860
}
{
数值:10
时间戳:1577836800
}, {
价值:12
时间戳:1577836810
}, {
值:17我在评论中提到了边缘设备的使用,它可以将值分配到适当的时间段。使用nodeJS服务来确定它必须更新哪些文档,因为它使查询集合变得更容易、更快
每个文档都可以使用此格式:
{
"period" : {
"start" : 1577836800,
"end" : 1577836820
},
"values": [
{
"value": 10
"timestamp": 1577836800
},
{
"value": 12
"timestamp": 1577836810
},
{
"value": 17
"timestamp": 1577836820
}
]
}
例如,当传感器向服务提供新值时。在这种情况下,值为2,获取最后一个文档,并将其与值中的最后一个值进行比较
如果新值小于上一个值,请使用以下信息创建一个新文档,当然不要忘记使用最后一个值的时间戳填写“period.end”来更新上一个文档
{
"period" : {
"start" : 1577836830,
"end" : null
},
"values": [
{
"value": 2
"timestamp": 1577836830
}
]
}
更新
我编写这个JavaScript脚本是为了从一个集合迁移,根据需求将数据处理为新格式,并将其插入新集合
function createSensorObject(start, value){
var doc = new Object();
doc.period = new Object();
doc.period["start"] = start;
doc.period["end"] = null;
doc.values = new Array();
var valueObject = new Object();
valueObject["value"] = value;
valueObject["timestamp"] = start;
doc.values.push(valueObject);
return doc;
}
function pushNewValueIntoSensorObject(doc, value, timestamp){
doc["period"]["end"] = timestamp;
var valueObject = new Object();
valueObject["value"] = value;
valueObject["timestamp"] = timestamp;
doc["values"].push(valueObject);
}
function closePeriodInSensorObject(doc) {
doc["period"]["end"] = doc["period"]["start"];
}
// New collection cursor to insert new values.
var sensorNewCursor = db.sensor_new;
// Using the aggregate pipeline to sort and using toArray to iterate through.
var sensorDocuments = db.sensor.aggregate([ { $sort: { "timestamp" : 1}}]).toArray();
// Temp array to store the new sensor objects.
var sensorObjectArray = new Array();
for(var i = 0; i < sensorDocuments.length; i++) {
// Working with the current document.
var currentDocument = sensorDocuments[i];
var value = currentDocument["value"];
var timestamp = currentDocument["timestamp"];
// Initially creating a new document.
if(i === 0) {
var sensorObject = createSensorObject(timestamp, value);
// If there is only one document then we need to close the document.
if(i === (sensorDocuments.Length - 1)) {
closePeriodInSensorObject(sensorObject);
}
// Push into temp array.
sensorObjectArray.push(sensorObject);
}
else{
// Get the previous value.
var previousValue = sensorDocuments[i - 1]["value"];
// Get the latest sensor object from the temp array.
var sensorObject = sensorObjectArray[sensorObjectArray.length - 1];
// When the new value is larger or equal to the previous value.
if(value >= previousValue) {
// Push the new value into the latest sensor object.
pushNewValueIntoSensorObject(sensorObject, value, timestamp);
}
else {
// Create new sensor object.
var sensorObject = createSensorObject(timestamp, value);
sensorObjectArray.push(sensorObject);
}
}
}
print(`Inserting ${sensorObjectArray.length} objects into the db.sensor_new collection.`);
// Insert the whole array into the new collection
sensorNewCursor.insert(sensorObjectArray);
这个查询的结果是28
[
{
"_id": null,
"total": 28
}
]
MongoPlayground根据新的文档结构:
我真的希望这能对您起作用,如果没有请评论。:)您是否要为每个时段创建一个新文档?这会使查询非常简单,但如果不是这样,那么我们需要创建一个JavaScript函数来找出时段(时间序列)是什么是的。是的,我每个周期都创建一个新对象。因此,上面代码中的每个对象都是一个新文档。对不起,我应该说清楚。不用担心,现在的挑战是,起始值和峰值与周期组合在一起分散在整个集合中。您是使用边缘设备插入文档还是您的sensor这样做?数据是由nodeJS服务编写的这是个好主意,但目前我的问题是数据已经在数据库中。最好是现在进行查询。然后我们必须编写javascript函数将数据迁移到新集合,因为这在查询中是不可能的。
[
{
"_id": null,
"total": 28
}
]