0

我知道在 Mongo 世界中,大数据,例如图像、音乐和视频都进入 GridFS,小型和结构数据直接进入 Mongo。

最近,我超出了BSONObj大小限制。我的文件,实际上是对象,看起来vector<vector<vector<Foo>>>像一个小的常规数据(具有嵌套结构),但具有巨大的大小(从 20Mb 开始)。我不确定,但是将它们写入 GridFS 并预先转换为 bytearray 似乎是一个坏主意(向量具有动态的、非恒定的长度)。有什么绕行吗?

可选地,我想对该对象执行查询,例如从顶级向量中获取第一个切片(索引)。

4

1 回答 1

1

根据您要支持的查询,我想到了两种选择。但是,我相信对于几百 MB 的数据大小,这些将比在 RAM 中执行所有操作并将 MongoDB 用作单纯的 blob 存储要慢:

1)您可以将每个维度放在一个单独的对象中:

FirstLevel {
   "_id" : ObjectId("..."),
   "Children" : [ ObjectId("..."), ... ]
   // list of vector ids (of the second level)
}

可能不是一个很好的解决方案。它仍然对您可以存储的项目数量施加了限制,但是数量应该非常大,因为如果是一个大对象 ,它大概(16M / id size)^3会小得多(在叶子中) 。Foo

访问会很慢,因为你必须走树。节点和叶子的数据格式有些不同。然而,非常可扩展(任何维度)。

2)由于您的数据是 3 维的,您可以将其存储为“真正的 3 维”:

Data {
  Coords : { "x" : 121, "y" : 991, "z" : 12 },
  ActualData : { /* Serialized Foo */ }
}

在元组上使用复合索引{x, y, z},这很好地支持了维度切片,除了像“全选z = 13,然后按顺序x这样的操作。这种方法会带来相当多的开销,您可能需要一个自定义(反)序列化器。我不知道 C++ 驱动程序,但在 C# 中这很容易实现。

这也将很好地支持锯齿状数组。

2a) 如果你不想要 2) 的开销,你可以将坐标压缩成一个long. 这类似于geohashing,这是 MongoDB 为其地理空间索引所做的。

查询坐标切片是一个位掩码操作,不幸的是,它还不支持查询($bit仅适用于更新)。不过,你可以投票给它

也许您也可以出于您的目的滥用地理哈希,但这只是实验性的。

于 2011-12-11T11:20:34.867 回答