我知道在Mongo世界中大数据,如图像,音乐和视频进入GridFS,小型和结构数据直接传递给Mongo。
最近,我超出了BSONObj
大小的限制。我的文件,实际上是对象,如vector<vector<vector<Foo>>>
看起来像一个小的常规数据(具有嵌套结构),但具有巨大的大小(从20Mb开始)。我不确定,但是通过事先转换为bytearray将它们写入GridFS似乎是一个坏主意(向量具有动态,非常量长度)。有一些解决方法吗?
Optionaly,我想对这些对象执行查询,例如从顶层向量中获取第一个切片(索引)。
答案 0 :(得分: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)由于您的数据是三维的,您可以将其存储为“真正的三维”:
Data {
Coords : { "x" : 121, "y" : 991, "z" : 12 },
ActualData : { /* Serialized Foo */ }
}
在{x, y, z}
元组上使用复合索引,这非常有效地支持维度切片,除了“select all z = 13
之类的操作,然后按x
排序”。这种方法带来了相当多的开销,你可能需要一个自定义(de)序列化器。我不知道C ++驱动程序,但在C#中很容易实现。
这也将很好地支持锯齿状阵列。
2a)如果你不想要2)的开销,你可以将坐标压缩成一个long
。这类似于geohashing,这是MongoDB为其地理空间索引所做的。
然后查询坐标切片是一个位掩码操作,遗憾的是,查询不支持这种操作($bit
仅适用于更新)。不过你可以vote for it。
也许你也可以为你的目的滥用geohashing,但那是相当实验性的。