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

Вступ до Mongoose для MongoDB та Node.js

by
Length:LongLanguages:
This post is part of a series called An Introduction to Mongoose for MongoDB and Node.js.
Bulk Import a CSV File Into MongoDB Using Mongoose With Node.js

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

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

Що таке MongoDB?

Насамперед розглянемо MongoDB. MongoDB - це база даних, що зберігає ваші дані як документи. Звичайно ці документи мають JSON (* JavaScript Object Notation - текстовий формат обміну даними, заснований на JavaScript. Тут і надалі примітка перекладача) - подібну структуру.

Потім документ розміщується усередину колекції. Наприклад, у вищезазначеному прикладі документу визначається об'єкт user. Далі цей об'єкт user став би, скоріше за все, частиною колекції під назвою users.

Одна із головних особливостей MongoDB - гнучкість структури ії даних. Незважаючи на те, що в першому прикладі об'єкт user мав властивості firstName та lastName, ці властивості можуть бути відсутніми в інших документах user колекції users. Саме це відрізняє MongoDB від баз даних SQL (* Structured Query Language - мова структурованих запитів), наприклад, MySQL чи Microsoft SQL Server, в яких для кожного об'єкту, що зберігається в базі даних, необхідна фіксована схема.

Завдяки здатності створювати динамічні об'єкти, що зберігаються у вигляді документів у базі даних, до справи береться Mongoose.

Що таке Mongoose?

Mongoose - це ODM (* Object Document Mapper - об'єктно-документний відображувач). Це означає, що Mongoose дозволяє вам визначати об'єкти зі строго-типізованою схемою, що відповідає документу MongoDB.

Mongoose дає величезний набір функціональних можливостей для створення та роботи зі схемами. Наразі Mongoose має вісім SchemaTypes (* типи даних схеми), котрі може мати властивість, що зберігається до MongoDB. Ці типи наступні:

  1. String
  2. Number
  3. Date
  4. Buffer
  5. Boolean
  6. Mixed
  7. ObjectId (* унікальний ідентифікатор об'єкта, первинний ключ, _id)
  8. Array

Для кожного типу даних можна:

  • зазначити значення за налаштуванням
  • зазначити функцію користувача для перевірки даних
  • зазначити, що поле необхідно заповнити
  • зазначити get-функцію (геттер), яка дозволяє вам проводити маніпуляції над даними до їх повернення у вигляді об'єкта
  • зазначити set-функцію (* сеттер), яка дозволяє вам проводити маніпуляції над даними перед їх зберіганням до бази даних
  • визначити індекси для більш швидкого отримання даних

Окрім цих спільних можливостей для деяких типів даних також можна налаштувати особливості зберігання та отримання даних із бази даних. Наприклад, для типу даних String можна зазначити наступні додаткові опції:

  • конвертація даних до нижнього регістру
  • конвертація даних до верхнього регістру
  • обрізання даних перед зберіганням
  • визначення регулярного виразу, який дозволяє в процесі перевірки даних обмежити дозволені для зберігання варіанти даних
  • визначення переліку, який дозволяє установити список припустимих рядків

Для властивостей типу Number і Date можна зазначити мінімально та максимально допустне значення.

Більшість із восьми допустних типів даних мають бути вам добре знайомі. Однак, деякі (Buffer, Mixed, ObjectId та Array) можуть викликати труднощі.

Тип даних Buffer дозволяє вам зберігати двійкові дані. Типовим прикладом двійкових даних може бути зображення чи закодований файл, наприклад, документ у PDF-форматі (*  формат передаваного документа).

Тип даних Mixed використовується для перетворення властивості в "неперебірливе" поле (поле, в якому припустимі дані будь-якого типу).Так само, як багато розробників використовують MongoDB для різних цілей, у цьому полі можна зберігати дані різного типу, оскільки відстутня визначена структура. Обачливо використовуйте цей тип даних, оскільки він обмежує можливості, надавані Mongoose, наприклад, перевірку даних та відстежування змін сутності для автоматичного оновлення властивості при зберіганні.

Тип даних ObjectId використовується звичайно для визначення посилання на інший документ у вашій базі даних. Наприклад, якщо б у вас була колекція книг та авторів, документ книги міг би містити властивість ObjectId, шо посилається на визначеного автора документа.

Тип даних Array дозволяє вам зберігати JavaScript-подібні масиви. Завдяки цьому типу даних ви можете виконувати над даними типові JavaScript операції над масивами, наприклад, push, pop, shift, slice і т.д.

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

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

Mongoose - це бібліотека JavaScript, що дозволяє вам визначати схеми зі строго-типізованими даними. Одразу після визначення схеми Mongoose дає вам можливість створювати Model (* модель), засновану на визначеній схемі. Потім модель синхронізується з документов MongoDB за допомогою визначення схеми моделі.

Одразу після визначення схем та моделей ви можете користуватися різними функціями Mongoose для перевірки, зберігання, видалення та запиту ваших даних, використовуючи звичайні функції MongoDB. Ми ще розглянемо це більш докладно на конкретних прикладах.

Встановлення MongoDB

До того, як почати створювати схеми та моделі Mongoose, нам необхідно установити та налаштувати MongoDB. Я би порадив вам відвідати сторінку завантаження MongoDB. Мається декілька різних варіантів установки. Я вибрав Community Server. Цей варіант дозволяє вам встановити версію, призначену саме для вашої операційної системи. Також MongoDB пропонує варіант Enterprise Server та варіант хмарної установки. Оскільки цілу книгу можна би було написати про установку, налаштування та моніторинґ MongoDB, я зупинився на варіанті Community Server.

Одразу після завантаження та установки MongoDB для обраної вами операційної системи, вам необхідно буде запустити базу даних. Замість того, щоб знову винаходити колесо, я хотів би запропонувати вам почитати документацію MongoDB про установку MongoDB версії Community.

Я зачекаю на вас, поки ви наналаштуєте MongoDB. Щойно ви упорались із вищезазначеним, ми можемо перейти до інсталяції Mongoose для з'єднання з вашою тільки-но встановленою базою даних MongoDB.

Встановлення Mongoose

Mongoose - це бібліотека JavaScript. Я збираюся використовувати її в додатку Node.js. Якщо Node.js у вас вже встановлено, то ви можете перейти до наступного розділу. Якщо ж ні, тоді я раджу вам почати з відвідування сторінки завантаження Node.js та вибору інсталятора для вашої операційної системи.

Тільки-но Node.js встановлено та налаштовано, я збираюся створити новий додаток і потім установити npm  (* пакетний менеджер Node) модуль Mongoose.

Після переходу у консолі до папки, куди б ви хотіли встановити ваш додаток, ви можете виконати настуні команди:

Під час ініціалізації мого додатку я залишив значення всіх запитуваних параметрів за налаштуванням. Тепер я встановлю модуль mongoose наступним чином:

Після виконання всіх необхідних попередніх умов, давайте підключимося до бази даних MongoDB. Я розташував наступний код у файлі index.js, оскільки я обрав його як стартову точку мого додатку:

В першому рядку коду ми підключаємо бібліотеку mongoose. Далі я відкриваю з'єднання з базою даних, що я назвав mongoose_basics, за допомогою функції connect.

Функція connect приймає ще два інших необов'язкових параметри. Другий параметр - об'єкт опцій, де ви можете зазначити, за необхідності, наприклад, username (им'я користувача) и password (пароль). Третій параметр, що може бути й другим, якщо у вас не визначені опції, - це функція зворотного виклику, що буде викликана після спроби з'єднання з базою даних. Функцію зворотного виклику можна використовувати двома способами:

Щоб уникнути потенційної необхідності вступу до JavaScript Promises, я буду використовувати перший спосіб. Нижче подається оновлений index.js:

Якщо виникла помилка при підключенні до бази даних, то викидається виняток, і все подальше виконання функції переривається. За відсутності помилки до консолі виводиться повідомлення про вдале з'єднання.

Тепер Mongoose встановлено та підключено до бази даних під назвою mongoose_basics. Моє з'єднання з MongoDB не використовує ні username, ні password, ні порту користувача. Якщо вам необхідно зазначити ці опції чи будь-яку іншу при підключенні, я раджу вам подивитися документацію Mongoose про підключення. В документації дається пояснення як багатьох доступних опцій, так і процесу створення декількох з'єднань, поєднання з'єднань, реплік тощо.

Після вдалого з'єднання давайте перейдемо до визначення схеми.

Визначення Mongoose Schema (*схеми)

На початку статті я показав вам об'єкт user, який мав дві властивості: firstName та lastName. У наступному прикладі я переробив цей документ у схему:

Це дуже проста схема, що містить усього-на-всього дві властивості без атрибутів, пов'язаних з нею. Давайте поширимо наш приклад, зробив властивості first і last name дочірніми об'єктами властивості name. Властивість name буде містити властивості first и last name. Також я додам властивість created типу Date.

Як ви бачите, Mongoose дозволяє мені створювати дуже гнучкі схеми з безліччю можливих комбінацій організації даних.

У наступному прикладі я збираюся створити дві нові схеми (author і book) та показати вам, як створювати зв'язок з іншою схемою. Схема book буде містити посилання на схему author.

Вище подається схема author, що поширює схему user, яку я створив у попередньому прикладі. Щоб пов'язати Author та Book, в схемі author першою властивістю зазначаємо _id типу ObjectId. _id - це стандартний синтаксис для позначення первинного ключа в Mongoose і MongoDB. Далі, як і в схемі user, я визначив властивість name, що містить first і last name автора.

Поширюючи схему user, схема author містить декілька додаткових властивостей типу String. Також я додав властивість типу Buffer, в якій можна було б розташувати зображення профілю автора. Остання властивість містить дату створення автора. Проте, ви можете звернути увагу на те, що вона створена трохи інакше, оскільки у ній зазначено значення за налаштуванням "зараз". При зберіганні автора до бази даних цій властивості буде надано значення поточної дати/часу.

Щоб завершити приклади схем, давайте створимо схему book, що містить посилання на автора, за допомогою властивості типу ObjectId.

Схема book містить декілька властивостей типу String. Як було вказано раніше, ця схема містить посилання на схему author. Схема book також містить властивість ratings типу Array, щоб продемонструвати вам можливості визначення схем. Кожний елемент цього масиву містить властивості summarydetailnumberOfStars та created date.

Mongoose надає вам можливість створювати схеми з посиланнями на інші схеми чи, як у прикладі вище з властивістю ratings, дозволяє створювати Array дочірніх властивостей, що може міститися у прив'язаній схемі (author у нашому прикладі) чи у поточній схемі, як у прикладі вище (схема book з властивістю ratings типу Array).

Створення та зберігання Mongoose Models (* моделей)

Оскільки на прикладі схем author та book ми побачили гнучкість схеми Mongoose, я збираюся продовжити використовувати їх і створити на їх основі моделі Author та Book.

Після зберігання моделі в MongoDB створюється Document (* документ) з тими ж властивостями, що визначені у схемі, на основі котрої була створена модель.

Щоб продемонструвати створення та зберігання об'єкта, у наступному прикладі я збираюся створити декілька об'єктів: одну модель Author і декілька моделей Book. Одразу після створення ці об'єкти будуть збережені до MongoDB за допомогою методу моделі save.

У прикладі вище я самим безсовісним чином розмістив посилання на дві мої нові книги. На початку прикладу ми створюємо та зберігаємо jamieObject, створений за допомогою моделі Author. Якщо виникла помилка всередині функції save об'єкта jamieObject, то додаток викине виняток. За відсутності ж помилки всередині функції save будуть створені та збережені два об'єкти book. Подібно до об'єкта jamieObject, в цих об'єктах при виникненні помилки під час зберігання викидається виняток. Інакше до консолі виводиться повідомлення про вдале зберігання.

Для створення посилання на Author, обидва об'єкти book посилаються на первинний ключ _id схеми author у властивості author схеми book.

Перевірка даних перед зберіганням

Узвичаєно наповнення даних для створення моделі у формі на веб-сторінці. Через це добре було б перевірити ці дані перед зберіганням моделі до MongoDB.

У наступному прикладі я оновив попередню схему author, додавши перевірку даних наступних властивостей: firstName, twitter, facebook та linkedin.

Для властивості firstName було визначено атрибут required. Тепер під час виклику функції save Mongoose поверне помилку з повідомленням про необхідність указання значення властивості firstName. Я вирішив зробити властивість lastName без необхідності вказання її значення на випадок, якщо авторами у моїй базі даних були б Cher чи Madonna (відсутнє прізвище).

Для властивостей twitter, facebook та linkedin використовуються подібні валідатори користувача. Вони перевіряються на відповідність початку їх значень відповідному доменному імені соціальних мереж. Оскільки це необов'язкові для заповнення поля, валідатор застосовується тільки у випадку надходження даних для цих властивостей.

Пошук та оновлення даних

Вступ до Mongoose не був би завершеним без прикладу пошуку запису та оновлення однієї чи більше властивостей цього об'єкту.

Mongoose надає декілька різних функцій для пошуку даних визначеної моделі. Ці функції наступні: findfindOne та findById.

Функції find и findOne отримують як аргумент об'єкт, що дозволяє виконувати складні запити. Функція ж findById отримує тільки одне значення функції зворотного виклику (скоро буде наведено приклад). У наступному прикладі я продемонструю вам, як можна зробити вибірку книг, що містять у своїй назві рядок 'mvc'.

Усередині функції find я виконую пошук нечутливого до регістру рядку 'mvc' за властивістю title. Це здійснюється за допомогою того ж синтаксису, що використовується для пошуку рядка у JavaScript.

Функцію find також можна "почепити" до інших методів запиту, наприклад, whereandorlimitsortany тощо.

Давайте поширимо наш попередній приклад, обмеживши кількість результатів до п'яти перших книг та відсортувавши їх за датою за зменшенням. Результатом будуть перші п'ять найновіших книг, що містять у назві рядок 'mvc'.

Після використання функції find порядок подальших функцій не має значення, оскільки з усіх зчеплених функцій формується єдиний запит і функції не виконуються до виклику функції exec.

Як я згадував раніше, функція findById виконується трохи інакше. Вона виконується одразу ж і приймає як один із аргументів функцію зворотного виклику, і не дозволяє "зчеплення" функцій. У наступному прикладі я запитую необхідного автора за його _id.

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

Одразу після повернення об'єкта ви можете змінити будь-яку його властивість та оновити її. Тільки-но ви внесли необхідні зміни, ви викликаєте метод save таким же чином, як ви робили і при пристворенні об'єкта. У наступному прикладі я поширю приклад із функцією findbyId та оновлю властивість linkedin автора.

Після вдалого отримання автора встановлюється значення властивості linkedin та викликається функція save. Mongoose здатна помітити зміну властивості linkedin та передати стан, оновлений тільки за модифікованими властивостями, до MongoDB. При виникненні помилки під час зберігання буде викинуто виняток і додаток перестане працювати. За відсутності помилок до консолі буде виведено повідомлення про вдалу зміну.

Також Mongoose надає можливість знайти об'єкт та одразу оновити його за допомогою функцій з відповідними назвами: findByIdAndUpdate та findOneAndUpdate. Давайте оновимо попередній приклад, щоб показати функцію findByIdAndUpdate у дії.

У попередньому прикладі властивості, що ми хочемо оновити, передаються до функції findByIdAndUpdate у якості об'єкта другим параметром. При цьому функція зворотного виклику є третім параметром. Після вдалого оновлення повернений об'єкт author містить оновлену інформацію. Він виводиться до консолі, щоб ми побачили оновлені властивості автора.

Повний код прикладу

Протягом статті ми розглядали кусочки коду, що описують роботу окремих дій, наприклад, створення схеми, створення моделі тощо. Давайте тепер об'єднаємо все докупи в одному повному прикладі.

Спочатку я створив два додаткових файли: author.js та book.js. Ці файли містять відповідні визначення схем і створення моделей. Останній рядок коду робить модель доступною для використання у файлі index.js.

Давайте почнемо з файлу author.js:

Далі переходимо до файлу book.js:

І, нарешті, оновлений файл index.js:

У вищезазначеному прикладі всі дії Mongoose містяться всередині функції connect.Файли author та book підключаються за допомогою функції require після підключення mongoose.

Якщо MongoDB запущено, то ви тепер можете запустити повний додаток Node.js за допомогою наступної команди:

Після зберігання деяких даних до бази я оновив файл index.js, додав функції пошуку, наступним чином:

Знову-таки, ви можете запустити додаток за допомогою наступної комнади: node index.js.

Резюме

Після прочитання цієї статті ви маєте бути у спромозі створювати надзвичайно гнучкі схеми та моделі Mongoose, виконувати просту та складну перевірку даних, створювати та оновлювати документи і, нарешті, виконувати пошук створених документів.

Сподіваюсь, тепер ви почуваєтеся впевненим користувачем Mongoose. Якщо ви хочете дізнатися більше про Mongoose, я би радив вам вивчити Mongoose Guides, у якому поясняються більш просунуті теми, наприклад, population, middleware, promises тощо.

Вдалого полювання (нехай пробачать мене мангусти)!

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.