Первоначально опубликовано вhttps://dev.to/shubhambattoo/uploading-files-to-mongodb-with-gridfs-and-multer-using-nodejs-5aed

Здравствуйте, в этом уроке мы научимся загружать файлы напрямую в MongoDB, используя спецификацию GridFS.

Если вы думаете, что TLDR; просто проверьте код завершения здесь.

Официальная документация объясняет, когда использовать эту спецификацию для загрузки файлов. Что резюмируется в следующем:

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

Поскольку GridFS хранит файлы фрагментами. Ниже представлены созданные коллекции:

  • chunks хранит двоичные фрагменты.
  • files хранит метаданные файла.

Предпосылки

  1. NodeJS LTS установлен
  2. MongoDB установлен на вашем локальном компьютере
  3. редактор кода

Настройка локального сервера NodeS

Создайте папку и измените каталог на нужную папку. Откройте командную строку в текущей папке и введите

npm init -y

Это создаст файл package.json со значениями по умолчанию.

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

npm install express mongoose ejs multer multer-gridfs-storag

Создайте файл с именем app.js в корне проекта. Требовать необходимые пакеты для создания сервера.

https://gist.github.com/shubhambattoo/63cbc31e9d1fd58f5d866f750442b2a8

Нам будет лучше создать скрипты для запуска веб-приложения из командной строки, перейти к вашему файлу package.json и в ключе scripts добавить следующее:

"scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  }

затем запустите npm start, и сервер должен запуститься на порту 5001. Вы должны увидеть один журнал в командной строке, указывающий, что сервер запущен на 5001.

Подключение к базе данных, инициализация GridFsStorage и создание хранилища

Требовать все необходимые пакеты

https://gist.github.com/shubhambattoo/613ed021ee9e51c065e9e1765db9c449

Mongoose — это ORM для MongoDB, который будет использоваться в этом руководстве. Multer — это промежуточное ПО NodeJS, которое облегчает загрузку файлов. А GridFsStorage — это механизм хранения GridFS для Multer, позволяющий хранить загруженные файлы непосредственно в MongoDB. Crypto и Path будут использоваться для создания уникального имени для загруженного файла.

https://gist.github.com/shubhambattoo/25907e91bb4b201701464cd45a1feb9f

Теперь инициализация GridFsStorage.

https://gist.github.com/shubhambattoo/262c29dab56c93201eb73d8310543519

Здесь мы используем собственный драйвер nodejs-mongodb-driver, который использует мангуст, и создаем GridFSBucket, мы передаем базу данных в ведро, вы можете видеть, что мы даем одно имя ведра, это имя ведра будет использоваться как имя коллекции .

https://gist.github.com/shubhambattoo/11f5c3171b22d037ddafca3455ec2134

Теперь мы инициализируем хранилище в соответствии с Multer GridFS и создаем случайные байты, используя метод randomBytes, присутствующий в криптобиблиотеке.

Здесь мы используем конструктор Promise для создания обещания, которое затем разрешается с помощью объекта fileInfo. Этот шаг не является обязательным, так как вы можете передать только ключ URL-адреса, и ведро будет работать нормально и не изменит имя файла. Например, вы можете использовать следующее:

const storage = new GridFsStorage({ url : mongoURI})

Далее давайте настроим наш внешний интерфейс с механизмом шаблонов и настроим экспресс для рендеринга шаблона.

Создание представления

Создайте новую папку с именем views в корне папки и внутри нее создайте файл с именем index.ejs. Здесь мы будем хранить наш внешний вид. Я не буду утомлять вас, ребята, созданием HTML и просто опубликую код для него. Я использую bootstrap для быстрого прототипирования.

https://gist.github.com/shubhambattoo/63dc5be0bad61a7c739b2be2f81ccb55

Настройка экспресс-приложения для визуализации представления. Настройте промежуточное ПО механизма просмотра на ejs

https://gist.github.com/shubhambattoo/ed4b5d6f9a4f2a6b9c36c15dff54a90a

Затем снова запустите сервер, перейдите в браузер и откройте http://localhost:5001, и вы должны увидеть одну страницу, отображаемую с только что созданным представлением.

Создайте запрос для обработки отправки формы и загрузки файла

https://gist.github.com/shubhambattoo/3dcc62894888a0a741d2f2d1af725e63

Как мы уже сделали большую часть нашей тяжелой работы при создании ковша для хранения, а мультер позаботится обо всем остальном. Нам просто нужно передать промежуточное ПО, а затем просто перенаправить на тот же URL-адрес.

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

https://gist.github.com/shubhambattoo/f99ce8a4f8e04619d06eed71385522eb

В корзине gridfs мы получаем доступ ко многим методам, одним из которых является find, который очень похож на обычный поиск в MongoDB и принимает имя файла в качестве первого аргумента, а затем мы конвертируем результат в массив и проверяем, есть ли какой-либо файл с такое имя файла, и если есть, мы используем другой метод, который присутствует в корзине gridfs, называемый openDownloadStreamByName, который затем снова принимает имя файла, а затем мы используем канал для возврата ответа клиенту.

До сих пор мы могли получить изображение с указанным выше маршрутом, но не могли отобразить его в нашем представлении, поэтому давайте создадим метод внутри маршрута, где мы отображали нашу страницу index.ejs.

https://gist.github.com/shubhambattoo/0390b23bb6e3eac4059b43e72ea46b31

Здесь вы можете увидеть много дополнительного кода, такого как сортировка массива, и вы можете его пропустить.

Теперь в шаблоне мы перебираем отправленные файлы, а затем показываем изображения под формой. Мы будем отображать только файлы типа jpg или png, эта проверка может быть обновлена ​​​​с помощью регулярного выражения и зависит от личных предпочтений.

https://gist.github.com/shubhambattoo/afe0fec21535d73a401a64b5a5266c70

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

https://gist.github.com/shubhambattoo/a37fcd1a4f60f62542fb43ee43d5ace4

Здесь мы получаем идентификатор в виде строки, поэтому его необходимо преобразовать в объектный идентификатор mongodb, а затем только метод ведра может удалить файл с соответствующим идентификатором. Я упростил задачу, не используя HTTP-метод удаления здесь, вы можете использовать его, если хотите, почтовый запрос здесь работает нормально.

Вывод

Как мы видим, MongoDB предоставляет хорошее решение для хранения файлов в базе данных и может пригодиться при создании веб-приложений с меньшим объемом хранилища, но имейте в виду, что вы можете хранить документы только до 16 МБ.

Поставьте лайк и пометьте репозиторий звездочкой, если он вам помог.