Правильный способ хранить большие файлы (но не медиа) в монго? - PullRequest
0 голосов
/ 10 декабря 2011

Я знаю, что в мире Монго большие данные, такие как изображения, музыка и видео, отправляются в GridFS, малые и структурированные данные отправляются непосредственно в Монго.

Недавно я превысил ограничение на BSONObj размер. Мои файлы, которые на самом деле объекты как vector<vector<vector<Foo>>>, выглядят как небольшие регулярные данные (с вложенной структурой), но с огромным размером (начиная с 20 МБ). Я не уверен, но запись их в GridFS с предварительным преобразованием в bytearray кажется плохой идеей (векторы имеют динамическую, непостоянную длину). Есть какой-нибудь обход?

Необязательно, я хочу выполнить запросы к этим объектам, например, получить первый фрагмент (индекс) из вектора верхнего уровня.

1 Ответ

1 голос
/ 11 декабря 2011

В зависимости от запросов, которые вы хотите поддержать, мне приходят на ум две альтернативы.Тем не менее, я считаю, что при размерах данных в пару сотен МБ это будет медленнее, чем все в оперативной памяти и использование 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 работает только для обновлений).Вы можете голосовать за него , хотя.

Возможно, вы могли бы также злоупотреблять геохэшингом, но это было бы довольно экспериментально.

...