Хранить файлы в mongodb с помощью Nodejs

Я сохранял свои файлы в FS моего сервера, и теперь я хочу сохранить их в mongodb (для упрощения резервного копирования и т.д.). Я хочу хранить файлы размером 4-5 Мб, и я попытался сохранить их с помощью мангуста с типом буфера. Я успешно сохранил их и восстановил их, но я заметил значительную медленную производительность при сохранении и извлечении файлов, таких как 4 или 5 Мб.

Моя схема:

let fileSchema = new Schema({
name: {type: String, required: true},
_announcement: {type: Schema.Types.ObjectId, ref: 'Announcements'},
data: Buffer,
contentType: String
});

Как я их извлекаю с сервера expressjs:

 let name = encodeURIComponent(file.name);
 res.writeHead(200, {
     'Content-Type': file.contentType,
     'Content-Disposition': 'attachment;filename*=UTF-8\'\'' + name
 });
 res.write(new Buffer(file.data));

Мой вопрос в том, следует ли мне использовать некоторые функции сжатия zlib, такие как "deflate" для сжатия буфера, прежде чем сохранять их в mongodb, а затем распаковать двоичный файл перед отправкой их клиенту? Это сделает весь процесс быстрее? Я что-то упустил?

Ответ 1

Похоже, вы пытаетесь сохранить действительно большое количество информации с помощью mongoDb.

Я могу представить три различных варианта для вашего случая

Облачные сервисы

  • Как уже комментируют другие люди, если сохраняемый вами файл является сжатым, даже если это небольшой файл, новое сжатие вам не поможет. В этом случае я рекомендую использовать какой-либо облачный веб-сервис, который уже оптимизирован для той информации, которую вы пытаетесь сохранить и извлечь, если это изображение, которое вы можете использовать Cloudinary, у которого также есть бесплатный сервис, чтобы вы могли проверить это.

Локальное хранение и сохранение маршрутов в БД

  • Другим решением может быть сохранение закодированных данных в файле .txt, хранение их в облаке или в вашей файловой системе, а затем только сохранение маршрутизации в базе данных. Таким образом, вы не будете зависеть от скорости mongoDB для ее извлечения, но у вас будет хороший способ узнать, где находятся файлы.

Использование MongoDB и GridFS

  • Таким образом, вы можете использовать определенный метод для хранения информации в MongoDB, который рекомендуется при работе с файлами размером 16 МБ. Официальная документация гласит:

Вместо того, чтобы хранить файл в одном документе, GridFS делит файл на части или части [1] и сохраняет каждый кусок как отдельный документ. По умолчанию GridFS использует размер чанка по умолчанию 255 кБ; то есть GridFS делит файл на фрагменты размером 255 кБ, за исключением последнего фрагмента.

И затем они говорят, в каких ситуациях вы можете использовать этот способ хранения информации:

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

  • Если ваша файловая система ограничивает количество файлов в каталоге, вы можете использовать GridFS для хранения необходимого количества файлов.
  • Если вы хотите получить доступ к информации из частей больших файлов без необходимости загрузки целых файлов в память, вы можете использовать GridFS для вызова разделов файлов, не считывая весь файл в память.
  • Если вы хотите, чтобы ваши файлы и метаданные автоматически синхронизировались и были развернуты на нескольких системах и объектах, вы можете использовать GridFS. При использовании географически распределенных наборов реплик MongoDB может автоматически распространять файлы и их метаданные среди нескольких экземпляров и средств mongod.

Надеюсь, это было полезно :)

Ответ 2

Я предложу вам использовать GridFS, это быстрее и очень удобно.

Для получения дополнительной информации, пожалуйста, проверьте этот URL: https://docs.mongodb.com/manual/core/gridfs/.

Если у вас есть какие-либо вопросы о GridFS, дайте мне знать.

Ответ 3

Если вы абсолютно уверены, что должны хранить изображения в своей базе данных, а не в файловой системе или других облачных сервисах, я не буду это комментировать.

Что касается вашего конкретного вопроса, GridFS - это респектабельный вариант, который люди используют и в производстве, и он хорошо справился со своей задачей. Я лично использовал его пару лет назад, но мой вариант использования изменился, поэтому перешел на другую среду. (Пожалуйста, проверьте ссылку SO, где люди обсуждают его производительность)

Вызывает беспокойство тот факт, что у вас есть изображения 4 МБ, если только вы не передаете изображения с огромной зависимостью от качества и большого разрешения - этого не должно происходить. Пожалуйста, сожмите ваши изображения перед их сохранением, сделайте это на веб-интерфейсе или бэкэнде (на ваш выбор), если вы сожмете их на самом веб-интерфейсе, это уменьшит время передачи пакетов.

Обсуждение масштаба GridFS

Модуль для бокового сжатия node.js

GridFS