Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Node.js

Пакетний імпорт CSV - файлу до MongoDB за допомогою Mongoose та Node.js

by
Length:LongLanguages:
This post is part of a series called An Introduction to Mongoose for MongoDB and Node.js.
An Introduction to Mongoose for MongoDB and Node.js

Ukrainian (українська мова) translation by AlexBioJS (you can also view the original English article)

Final product image
What You'll Be Creating

Радий, що можу обговорити цю тему. У багатьох веб-додатках доволі часто відбувається отримання даних користувача та зберігання одного запису до вашої бази даних. Проте, як щодо того, коли ваші користувачі (чи ви самі) хочуть виконати масове вставлення однією командою?

Читайте статтю далі, щоб дізнатися, як створювати шаблон CSV (comma-separated values - значення, відокремлені комами) - файлу та форму для завантаження CSV - файлу та як виконати парсинг CSV - файлу для створення моделі Mongoose, яку збережемо до бази даних MongoDB.

Припускається, що ви маєте базові уявлення про Mongoose та її взаємодію з MongoDB. Якщо ж їх нема, то я раджу вам для початку прочитати мою статтю Вступ до Mongoose для MongoDB та Node.js. У ній повідомляється, як Mongoose взаємодіє з MongoDB способом створення строго-типізованих схем, з яких створюється модель. Якщо ви вже добре розумієте Mongoose, поїхали далі. У ній повідомляється, як Mongoose взаємодіє з MongoDB способом створення строго-типізованих схем, з яких створюється модель. Якщо ви вже добре розумієте Mongoose, поїхали далі.

Початок роботи

Для початку давайте створимо новий додаток Node.js. Перейдіть у командному рядку до директорії, куди ви хочете встановити ваш додаток Node.js, і виконайте наступні команди:

Я залишив значення за налаштуванням як є, тому мій додаток запуститься за допомогою файлу index.js. Спершу, до створення та парсингу CSV - файлів, нам необхідно виконати початкові налаштування. Я хочу створити веб-додаток. Для цього я збираюся доручити виконання всіх основних налаштувань сервера модулю Express. Для встановлення Express виконайте в консолі наступну команду:

Оскільки наш веб-додаток буде приймати файли за допомогою веб-форми, я збираюся також використовувати підмодуль Express Express File Upload. Давайте тепер установимо і його:

Цієї початкової конфігурації достатньо, щоб установити мій веб-додаток і створити базову веб-сторінку з формою для завантаження файлів до сервера.

Нижче наводиться мій index.js, у якому встановлюється мій веб-сервер:

У цьому прикладі ми підключаємо модулі Express та Express File Upload, налаштовуємо веб-додаток на використання File Upload та прослуховуємо підключення на 80 порту. Також у даному прикладі ми створили за допомогою Express маршрут для оброблення запитів до "/" , по якому буде відсилатися цільова сторінка за налаштуванням мого веб-додатку. У відповідь на запити по цьому шляху відправляється файл index.html, у якому міститься веб-форма, що дозволяє користувачеві вивантажити CSV - файл. Оскільки додаток працює на моєму локальному комп'ютері, то у моєму випадку при переході до http://localhost я побачу форму, що створю в наступному прикладі.

Нижче наводиться моя сторінка index.html з формою для вивантаження CSV - файлу:

У цьому HTML-файлі є два важливі моменти:

  1. Посилання на "/template", при клацанні якого буде скачано шаблон CSV - файлу, який можна заповнити інформацією, що необхідно переслати.
  2. Форма, властивості encType якої надано значення multipart/form-data, та поле для вводу типу file, що приймає файли з розширенням "csv".

Як ви могли помітити, HTML-файл посилається на шаблон Author. Якщо ви читали мою статтю 'Вступ до Mongoose...', то пам'ятаєте, що я створив схему Author. У цій статті я збираюся відтворити цю схему та створити для користувача можливість масового імпорту колекції авторів до моєї бази даних MongoDB. Давайте подивимося на схему Author. Проте, ви, певно, здогадались, що спочатку нам необхідно встановити модуль Mongoose:

Тепер, коли в нас встановлено Mongoose, давайте створимо новий файл author.js, у якому визначимо схему та модель Author:

Тепер, коли в нас встановлено Mongoose, давайте створимо новий файл author.js, у якому визначимо схему та модель Author:

Після створення схеми та моделі Author давайте переключимося та зосередимося на створенні шаблону CSV - файлу, який можна завантажити, клацнувши посилання шаблону. Для спрощення генерації шаблону CSV - файлу я збираюся використовувати модуль JSON (JavaScript Object Notation - текстовий формат обміну даними, заснований на JavaScript) to CSV. Давайте тепер установимо його:

Тепер я збираюся оновити мій заздалегідь створений файл index.js, щоб додати новий маршрут для оброблення запитів до "/template":

Я навів тільки новий код для маршруту шаблону, що додаємо до попереднього файлу index.js.

У коді відбувається наступне: підключення нового файлу template.js (буде створено наступним) і створення маршруту для оброблення запитів до "/template". При запитах до шляху цього маршруту буде викликано функцію get у файлі template.js.

Тепер, коли у нас оновлено сервер Express додаванням нового маршруту, давайте створимо новий файл template.js:

У цьому файлі я спочатку підключаю заздалегідь установлений модуль json2csv. Потім створюю та експортую функцію get. Ця функція приймає в якості аргументів об'єкти запиту та відповіді від серверу Express.

Усередині функції я створив масив полів, які хочу використовувати у моєму шаблоні CSV - файлу. Створити список полів можна різними способами. Перший (який я використав у цьому прикладі) - це створення статичного списку полів, які необхідно включити до шаблону. Другий - це динамічне створення списку полів способом вибирання властивостей із схеми Author.

Другий спосіб можна було б виконати за допомогою наступного коду:

Я б захотів використовувати цей динамічний метод, якщо б не труднощі, які виникають, якщо я не хочу включати безліч властивостей із схеми до шаблону CSV - файлу. У моєму прикладі у шаблоні не використовуються властивості _id і created, оскільки їх значення будуть задані за допомогою коду. Однак, якщо у вас немає полів, котрі ви хочете вилучити, то динамічний спосіб також підходить.

Створення шаблону CSV - файлу

Після визначення масиву полів я використовую модуль json2csv для створення із об'єкта JavaScript шаблону файлу. Цей об'єкт csv буде результатом запитів до маршруту зі шляхом '/template'.

І, нарешті, використовуючи властивість res сервера Express, я встановлюю значення двох заголовків, що забезпечить завантажування файлу authors.csv.

Якщо б ви запустили ваш Node-додаток зараз і перейшли в своєму веб-браузері за посиланням http://localhost, то на екрані відобразилась би веб-форма з посиланням для завантаження шаблону. Клацнувши посилання для завантаження шаблону, ви завантажите файл authors.csv для заповнення перед вивантаженням.

Нижче наводиться приклад заповненого CSV - файлу:

Результатом вивантаження цього шаблону буде створення двох авторів: мене та мого друга, який написав книгу про Node.js декілька років тому. Ви, скоріш за все, помітили, що в кінці кожного рядка розташовані три коми ",,,". Це зроблено задля скорочення прикладу. Я не заповнив властивості соціальних мереж (twitter, facebook і linkedin).

Кусочки мозаїки починають збиратися докупи та формувати загальну картину. Давайте перейдемо до найважливішого нашого прикладу та виконаємо парсинг CSV - файлу. Нам необхідно трохи оновити файл index.js для підключення до MongoDB і створення нового маршруту для оброблення запитів POST, по якому до сервера завантажується файл.

Після підключення до бази даних і налаштування нового маршруту для оброблення запитів POST прийшов час виконати парсинг CSV - файлу. На щастя, для цього є декілька відмінних бібліотек. Я вирішив використовувати модуль fast-csv, який ви можете встановити за допомогою наступної команди:

Маршрут для оброблення запитів POST було створено подібно до маршруту шаблону. У ньому викликається функція post із файлу upload.js. Нема необхідності розміщати функції маршрутів до різних файлів. Однак, мені хочеться зробити різні файли для цих маршрутів, оскільки це допомагає підтримувати читабельність і організованість коду.

Відправлення даних

І, нарешті, давайте створимо файл upload.js, в якому міститься функція post, яку викликаємо після відправки заздалегідь створеної форми:

Доволі багацько відбувається в цьому файлі. У перших трьох рядках ми підключаємо необхідні модулі, які знадобляться для здійснення парсингу та зберігання даних CSV - файлу.

Далі визначається та експортується функція post для використання у файлі index.js. Саме усередині цієї функції відбувається чарування.

Спочатку функція перевіряє наявність файлу в тілі запиту. Якщо файлу нема, тоді повертається помилка, яка вказує, що необхідно вивантажити файл.

Коли файл вивантажено, посилання на файл зберігається до змінної з іменем authorFile завдяки звертанню до масиву files і властивості file цього масиву. Ім'я властивості file відповідає імені поля для відправки файлу, яке я зазначив у прикладі index.html.

Також я створив масив authors, який буде наповнюватися поки виконується парсинг CSV - файлу. Цей масив буде використовуватися для зберігання даних до бази даних.

Далі викликається бібліотека fast-csv під час використання її функції fromString. Функція приймає CSV - файл у вигляді рядка. Я вибрав рядок із властивості authorFile.data. Властивість data містить вміст мого вивантаженого CSV - файлу.

Я передав дві опції до функції fromString модуля fast-csv: headers і ignoreEmpty. Значеннями обох є true. Це повідомляє бібліотеці, що в першому рядку CSV - файлу буде міститися заголовки і що необхідно ігнорувати порожні рядки.

Тепер, коли опції налаштовано, я визначив дві функції обробки подій, що викликаються при генеруванні подій data и end. Подія data генерується раз для кожного рядка CSV - файлу. У цій події міститься об'єкт JavaScript даних, що піддалися парсингу.

Я оновлюю цей об'єкт для включення властивості _id схеми Author з новим значенням типу ObjectId (унікальний ідентифікатор об'єкта, первинний ключ, _id). Далі цей об'єкт додається до масиву authors.

Після того, як відбувся парсинг усього CSV - файлу, генерується подія end. Усередині функції зворотного виклику для цієї події я викликаю функцію create моделі Author, передаючи їй масив authors.

Якщо під час зберігання масиву відбувається помилка, то викидається виняток. В іншому випадку користувачеві відображується повідомлення про кількість авторів, вивантажених і збережених до бази даних.

На випадок, якщо ви б хотіли побачити весь код, я створив репозиторій GitHub з кодом.

Завершення

У моєму прикладі я вивантажив тільки декілька записів. Якщо у вашому випадку необхідне вивантаження тисяч записів, то було б непогано зберігати записи невеликими частинами.

Це можна здійснити різними способами. Якщо б мені потрібно було це реалізувати, то я б запропонував оновити функцію зворотного виклику, зареєстровану на подію data, додавши перевірку довжини масиву authors. У випадку перевищення довжини масиву встановленої вами довжини, наприклад, 100, викличте функцію Author.create для цього масиву і потім скиньте (присвойте значення 0) масив. Потім функція збереже записи частинами по 100. Пересвідчіться, що залишили останній виклик функції create у функції зворотного виклику, зареєстрованій на подію end, для зберігання кінцевих записів.

Тіштеся!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.