我正在处理的MongoDB集合从手机中获取传感器数据,并且每2-6秒钟发送到服务器。
这些数据量很大,4-5小时后就会超过16MB的限制,看起来没有任何解决方法?
我尝试在Stack Overflow上搜索并查看了各种问题,但没有人真正分享他们的技巧。
是否有任何方式...可能是在DB端,可以像通过gridFS对大文件进行操作一样分配块?
我正在处理的MongoDB集合从手机中获取传感器数据,并且每2-6秒钟发送到服务器。
这些数据量很大,4-5小时后就会超过16MB的限制,看起来没有任何解决方法?
我尝试在Stack Overflow上搜索并查看了各种问题,但没有人真正分享他们的技巧。
是否有任何方式...可能是在DB端,可以像通过gridFS对大文件进行操作一样分配块?
{
_id : ObjectId("xxx"),
sensor : "SensorName1",
readings : [
{ date : ISODate("..."), reading : "xxx" },
{ date : ISODate("..."), reading : "xxx" },
{ date : ISODate("..."), reading : "xxx" }
]
}
在上述结构中,已经存在一个主要缺陷,即读取数组可能会呈指数增长,并超出16mb文档限制。
因此,我们可以稍微改变结构,使其看起来像这样,包含一个计数属性:
{
_id : ObjectId("xxx"),
sensor : "SensorName1",
readings : [
{ date : ISODate("..."), reading : "xxx" },
{ date : ISODate("..."), reading : "xxx" },
{ date : ISODate("..."), reading : "xxx" }
],
count : 3
}
这个想法是,当你向嵌入式数组中$push读取的时候,每次执行推送操作时,你都会增加($inc)计数变量。当你执行此更新(push)操作时,你需要在这个"count"属性上包含一个过滤器,它可能看起来像这样:
这背后的思路是,在你将阅读内容$push到嵌入式数组中时,你需要为每次执行的推送操作增加($inc)计数变量。并且在执行此更新(push)操作时,你需要在该"count"属性上包含一个过滤器,可能如下所示:
{ count : { $lt : 500} }
然后,设置您的更新选项,以便您可以将“upsert”设置为“true”:
db.sensorReadings.update(
{ name: "SensorName1", count { $lt : 500} },
{
//Your update. $push your reading and $inc your count
$push: { readings: [ReadingDocumentToPush] },
$inc: { count: 1 }
},
{ upsert: true }
)
有关MongoDb Update和Upsert选项的更多信息,请参见此处:
当过滤条件不满足时(即当此传感器没有现有文档或计数大于或等于500时 - 因为每次推送项目时都会增加计数),将创建一个新文档,并且读数现在将嵌入到此新文档中。因此,如果正确执行此操作,则永远不会达到16mb限制。
现在,当查询特定传感器的读数时,您可能会收到该传感器的多个文档返回(而不是一个包含所有读数的文档),例如,如果您有10,000个读数,则会返回20个文档,每个文档包含500个读数。
然后,您可以使用聚合管道和$unwind来过滤读数,就像它们是自己的单独文档一样。
有关unwind的更多信息,请参见此处,它非常有用
希望这可以帮助您。
你可以使用 MongoDB 中的 GridFS 来处理这种类型的情况。
GridFS 将文件分成多个部分或块1,并将每个块作为单独的文档存储,而不是将文件存储在单个文档中。默认情况下,GridFS 使用 255 kB 的块大小;也就是说,GridFS 将一个文件分成 255 kB 的块,最后一个块除外。最后一个块仅尽可能大。同样,小于块大小的文件只有最后一个块,使用尽可能少的空间加上一些附加元数据。
GridFS 的文档包含了实现 GridFS 所需的几乎所有内容。您可以按照文档进行操作。
由于您的数据是流数据,因此可以尝试以下方法...
gs.write(data, callback)