В зависимости от запросов, которые вы хотите поддержать, мне приходят на ум две альтернативы.Тем не менее, я считаю, что при размерах данных в пару сотен МБ это будет медленнее, чем все в оперативной памяти и использование MongoDB в качестве простого хранилища больших двоичных объектов:
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}
, он очень хорошо поддерживает размерные срезы, за исключением таких операций, как "выбрать все z = 13
, затем упорядочить по x
" .Этот подход требует значительных накладных расходов, и вам, вероятно, понадобится пользовательский (де) сериализатор.Я не знаю драйвера C ++, но в C # это очень легко реализовать.
Это также будет достаточно хорошо поддерживать зубчатые массивы.
2a) Если вы не хотите использовать издержки 2), вы можете сжать координаты в один long
.Это будет похоже на geohashing , что MongoDB делает для своих геопространственных индексов.
Запрос фрагментов координат - это операция с битовой маской, которая, к сожалению, пока не поддерживается для запросов ($bit
работает только для обновлений).Вы можете голосовать за него , хотя.
Возможно, вы могли бы также злоупотреблять геохэшингом, но это было бы довольно экспериментально.