MongoDB解决方案适用于16mb以上的文档?

MongoDB解决方案适用于16mb以上的文档?,mongodb,Mongodb,我正在处理的MongoDB的收集从手机上获取传感器数据,并每隔2-6秒ping一次到服务器 数据量巨大,4-5小时后超过16mb的限制,似乎没有任何解决办法 我曾尝试在Stack Overflow上搜索它,并讨论了各种问题,但实际上没有人分享他们的破解方法 有没有办法。。。在DB端,哪一个会像通过gridFS分发大文件一样分发块 您可以在MongoDB中使用GridFS处理这种情况 GridFS没有将文件存储在单个文档中,而是将文件划分为多个部分或块,并将每个块存储为单独的文档。默认情况下,Gr

我正在处理的MongoDB的收集从手机上获取传感器数据,并每隔2-6秒ping一次到服务器

数据量巨大,4-5小时后超过16mb的限制,似乎没有任何解决办法

我曾尝试在Stack Overflow上搜索它,并讨论了各种问题,但实际上没有人分享他们的破解方法


有没有办法。。。在DB端,哪一个会像通过gridFS分发大文件一样分发块

您可以在MongoDB中使用GridFS处理这种情况

GridFS没有将文件存储在单个文档中,而是将文件划分为多个部分或块,并将每个块存储为单独的文档。默认情况下,GridFS使用255kb的块大小;也就是说,GridFS将文件划分为255kb的块,最后一个块除外。最后一个块仅为所需的大小。类似地,不大于块大小的文件只有最后一个块,只使用所需的空间和一些额外的元数据

的文档包含实现GridFS所需的几乎所有内容。你可以跟着它

由于您的数据是流式的,您可以尝试以下操作

当数据是缓冲区或字符串时,回调将获取两个参数—错误对象(如果发生错误)和结果值,该值指示写入是否成功。当GridStore未关闭时,每次写入都会附加到打开的GridStore


您可以按照此操作获取流媒体相关信息。

要解决此问题,您需要对数据结构进行一些小的修改。听上去,要使文档超过16mb的限制,您必须将传感器数据嵌入单个文档中的数组中

我不建议在这里使用GridFS,我不认为这是最好的解决方案,下面是原因

有一种被称为bucketing的技术,你可以使用它将你的传感器读数分割成单独的文件,为你解决这个问题

其工作方式如下:

假设我有一个文档,其中包含特定传感器的一些嵌入式读数,如下所示:

{
    _id : ObjectId("xxx"),
    sensor : "SensorName1",
    readings : [
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" }
    ]
}
{ count : { $lt : 500} }
在上面的结构中,已经存在一个主要缺陷,读取数组可能会呈指数增长,并超过16mb文档限制

因此,我们可以做的是稍微更改结构,使其看起来像这样,以包含count属性:

{
    _id : ObjectId("xxx"),
    sensor : "SensorName1",
    readings : [
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" }
    ],
    count : 3
}
这背后的想法是,当您$push您的读取到您的嵌入式数组中时,您为执行的每个push增加($inc)count变量。当您执行此更新(推送)操作时,您将在这个“count”属性上包含一个过滤器,它可能看起来像这样:

{
    _id : ObjectId("xxx"),
    sensor : "SensorName1",
    readings : [
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" }
    ]
}
{ count : { $lt : 500} }
然后,设置更新选项,以便可以将“upsert”设置为“true”:

有关MongoDb更新和Upsert选项的更多信息,请参见此处:

将发生的情况是,当不满足过滤条件时(即,此传感器没有现有文档,或者计数大于或等于500-因为您每次推送一个项目时都会递增),将创建一个新文档,并且读数将嵌入此新文档中。因此,如果操作得当,您将永远不会达到16mb的限制

现在,当查询数据库中某个传感器的读数时,您可能会返回该传感器的多个文档(而不是一个包含所有读数的文档),例如,如果您有10000个读数,您将返回20个文档,每个文档包含500个读数

然后,您可以使用聚合管道和$unwind来过滤您的读数,就像它们是它们自己的单独文档一样

有关展开的更多信息,请参见此处,它非常有用


我希望这会有所帮助。

无限增长的文档是一种反模式;您可能应该重新考虑您的数据模型,以便更好地支持您的用例。GridFS方法仅适用于存储大型二进制blob的情况;这对包含您计划查询的字段的数据没有帮助(除非查询仅限于关于GridFS中二进制文件的元数据)。对于模式建议,您需要发布一个示例文档,并描述常见的更新和查询。您的MongoDB服务器版本和配置的存储引擎也是相关的。数据每1-2秒ping一次,因此如果我们决定对其进行缓冲并生成文件,它可能会干扰进程,从应用程序到服务器的负载也是一个因素。您的数据是以流的形式提供的吗?是的,通过套接字。这是最好的方法。要阅读更多关于bucketing的信息,您可以访问这里:谢谢!这实际上是我寻找的一个出色的解决方案。您能否提供一个通过聚合或其他方法提取数据的示例?16MB的限制是否也适用于聚合结果?此策略是否需要在计数字段处建立索引?(或复合索引名+计数?)是。每当读取字段时,它都应该被索引覆盖。在这种情况下,它作为更新条件的一部分被读取。