使用日期和值从传感器中删除冗余数据
Posted
技术标签:
【中文标题】使用日期和值从传感器中删除冗余数据【英文标题】:Remove redundant data from sensors by using date and value 【发布时间】:2016-09-27 08:44:37 【问题描述】:我正在开发一个从传感器收集数据的应用程序,我需要通过使用值(温度)和日期(时间戳)减少存储在 mongodb 数据库中的数据量 .
文档格式如下:
temperature: 10,
timestamp: ISODate("2016-04-29T14:37:50.370Z")
sensorCode:"SENSOR_A1"
问题在于传感器发送数据过于频繁,因此在短时间内(比如 10 分钟)内包含过多数据的文档过多。我的意思是在很短的时间内拥有多个相等的值是没有用的。 示例:这里有来自传感器的数据报告温度为 10
// collection: datasensors
[
temperature: 10,
timestamp: ISODate("2016-04-29T14:37:50.370Z")
sensorCode:"SENSOR_A1"
,
temperature: 10,
timestamp: ISODate("2016-04-29T14:38:50.555Z")
sensorCode:"SENSOR_A1"
,
temperature: 10,
timestamp: ISODate("2016-04-29T14:38:51.654Z")
sensorCode:"SENSOR_A1"
,
temperature: 10,
timestamp: ISODate("2016-04-29T14:50:20.335Z")
sensorCode:"SENSOR_A1"
]
因为不需要精确,我想删除从 2016-04-29T14:37:50.370Z 到 2016-04-29T14:38:51.32Z 的所有文档,除了一个。所以结果应该是这样的:
[
temperature: 10,
timestamp: ISODate("2016-04-29T14:38:51.654Z")
sensorCode:"SENSOR_A1"
,
temperature: 10,
timestamp: ISODate("2016-04-29T14:50:20.335Z")
sensorCode:"SENSOR_A1"
]
我要执行的移除操作应将小于 10 分钟的时间范围内的相等温度“降低”到一个值。
有什么技术可以做到这一点吗?
【问题讨论】:
【参考方案1】:我简化了我的解决方案,并决定在 10 分钟的时间窗口内接收到每个唯一的测量值。 为此需要 Mongo 3.2
-
添加时间标记会以 10 分钟时间组分隔测量值
然后我们将保留组中的第一条记录并存储所有 ID 以供后续处理
然后从所有 id 的数组中删除我们想要保留的文档的 id(比如说要删除的文档)
最后,作为 forEach 循环,我们将删除不需要的 id - 此行已注释 :-)
将下面的代码复制到mongo控制台,执行并验证要删除的id,然后取消注释并GO!
var addTimeMark =
$project :
_id : 1,
temperature : 1,
timestamp : 1,
sensorCode : 1,
yearMonthDay :
$substr : [
$dateToString :
format : "%Y%m%d%H%M",
date : "$timestamp"
, 0, 11]
var getFirstRecordInGroup =
// take only first record froum group
$group :
_id :
timeMark : "$yearMonthDay",
sensorCode : "$sensorCode",
temperature : "$temperature"
,
id :
$first : "$_id"
,
allIds :
$push : "$_id"
,
timestamp :
$first : "$timestamp"
,
totalEntries :
$sum : 1
var removeFirstIdFromAllIds =
$project :
_id : 1,
id : 1,
timestamp : 1,
totalEntries : 1,
allIds :
$filter :
input : "$allIds",
as : "item",
cond :
$ne : ["$$item", "$id"]
db.sensor.aggregate([
addTimeMark,
getFirstRecordInGroup,
removeFirstIdFromAllIds,
]).forEach(function (entry)
printjson(entry.allIds);
// db.sensor.deleteMany(_id:$in:entry.allIds)
)
每一步之后的文档外观如下:
"_id" : ObjectId("574b5d8e0ac96f88db507209"),
"temperature" : 10,
"timestamp" : ISODate("2016-04-29T14:37:50.370Z"),
"sensorCode" : "SENSOR_A1",
"yearMonthDay" : "20160429143"
2:
"_id" :
"timeMark" : "20160429143",
"sensorCode" : "SENSOR_A1",
"temperature" : 10
,
"id" : ObjectId("574b5d8e0ac96f88db507209"),
"allIds" : [
ObjectId("574b5d8e0ac96f88db507209"),
ObjectId("574b5d8e0ac96f88db50720a"),
ObjectId("574b5d8e0ac96f88db50720b")
],
"timestamp" : ISODate("2016-04-29T14:37:50.370Z"),
"totalEntries" : 3
最后一个;
"_id" :
"timeMark" : "20160429143",
"sensorCode" : "SENSOR_A1",
"temperature" : 10
,
"id" : ObjectId("574b5d8e0ac96f88db507209"),
"allIds" : [
ObjectId("574b5d8e0ac96f88db50720a"),
ObjectId("574b5d8e0ac96f88db50720b")
],
"timestamp" : ISODate("2016-04-29T14:37:50.370Z"),
"totalEntries" : 3
【讨论】:
以上是关于使用日期和值从传感器中删除冗余数据的主要内容,如果未能解决你的问题,请参考以下文章