0

我有以下架构的集合:

{
  "_id" : ObjectId("502e66f201f04e16a8885e8c"),
  "sensorID" : 2,    // id of the sensor
  "loc" : [3, 2],    // location of the sensor x,y
  "time" : new Date("Fri, 17 Aug 2012 19:44:50 GMT +04:00")   // time of the last meausurement
}

所以网络中的传感器很少。他们正在移动,每隔 x 秒他们就会告诉服务器他们的下落。

我想找到每个传感器的最后通知位置。

我想做的是:

db.runCommand({distinct: 'points', key: 'sensorID'})

选择所有不同的传感器,但我不知道最后一次应该在哪里放置额外的约束。

还有最重要的问题。我真的应该在mongo中这样做吗?可能是使用 MySql 更好

4

1 回答 1

0

传感器是否几乎同时报告并且部分陈旧数据是否可以容忍?

基本上有很多方法可以解决这个问题。

一种是,做一些类似于 db.collection.find({}).sort( {time: -1}).limit( #Number of sensors#) 的事情,这实际上是一个 MAX 函数,它会给你传感器的最新位置。然而,这种方法只有在所有传感器同时广播时才有效,当然如果其他传感器之一的报告速度特别慢,那么一个传感器当然容易出现部分陈旧数据或重复数据,例如一个传感器的竞争条件自慢速传感器上次更新以来已更新两次,导致它在列表中出现两次,不包括慢速传感器。. 可以通过附加上面的 distinct 子句来解决这个问题,但是这仍然可能导致潜在的过时数据,但最多只能关闭一次。如果每隔一段时间落后一个周期并不是什么大不了的事,那么这是合理的。

另一种方法是一次查询每个传感器,例如

db.collection.find({ "sensorID : #sensorID#"}).sort( { time: -1}).limit(1);

另一种方法是将您的架构更改为具有“最新”标志。并且在插入新的传感器点和时间时,只需查询该传感器的旧“最新”文档并将其更新为 false。这涉及到一点错误处理,因为您永远不会想要没有“最新”并且您正在查询的情况。因此,更好的方法是首先将您要插入的新文档的标志设置为真。然后将旧文档标志更新为 false。然后,如果您在更新之间一次搜索一个,则可以对两者进行排序并添加 1 的限制以获取最新的。否则,如果您想一次搜索所有传感器并返回所有传感器的列表,并且它发生在更新之间,

或者,您可以通过添加 mapreduce 函数和对传感器进行分组并按时过滤来干净地做到这一点。

希望这可以帮助。

于 2012-08-30T17:02:12.653 回答