Mongoose
Mongoose представляє спеціальну ODM-бібліотеку (Object Data Modelling) для роботи з MongoDB. Найчастіше бібліотека Mongoose служить зручним засобом для застосування структурованої схеми до колекції MongoDB. Модуль служить зручним засобом застосування структурних схем до документів. Також дає можливість достовірної перевірки типів даних та можливостей валідації. Офіційну документацію можна подивитися тут
Підключення
Для роботи з Mongoose необхідно встановити бібліотеку:
npm install mongoose -S
Насамперед треба підключити mongoose:
const mongoose = require('mongoose');
Щоб не працювати з callback функціями при зверненні до бази даних, а з
об'єктами promise, необхідно спочатку встановити їхню реалізацію для властивості
Promise
, екземпляра mongoose
:
mongoose.Promise = global.Promise;
Підключення до бази виконується методом mongoose.connect()
, в який першим
параметром передається адреса на підключення до бази даних, а другим об'єкт
налаштувань:
mongoose.connect(process.env.DB_HOST, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
За допомогою методу mongoose.disconnect()
можна відключитися від бази даних.
Схема документа
Однією з переваг ODM Mongoose є те, що дані можна описати певною схемою.
Експортуємо клас Schema
const Schema = mongoose.Schema;
Встановлюємо схему
const cats = new Schema({
nickname: String,
age: Number,
});
Схема містить метадані об'єктів. Тут указується, які властивості буде мати об'єкт і який буде тип даних. Для типів даних можна вказувати одне з наступних значень:
String
Number
Date
Buffer
Boolean
Mixed
Objectid
Array
Для складних властивостей як об'єкт замість типу вказується визначення цього об'єкта: Приклад:
const cats = new Schema({
nickname: String,
age: Number,
owner: {
name: String,
address: [String], // тип - массив строк
birthday: Date,
},
});
При визначенні схеми Mongoose має вбудовані правила валідації, які можна вказати у схемі:
required
: вимагає обов'язкової наявності значення для якостіmin
таmax
: задають мінімальне та максимальне значення для числових данихminlength
таmaxlength
: задають мінімальну та максимальну довжину для рядківenum
: рядок повинен представляти одне із значень у зазначеному масиві рядківmatch
: рядок повинен відповідати регулярному виразу
const cats = new Schema({
nickname: {
type: String,
minlength: 2,
maxlength: 7,
required: [true, 'Nickname is required'],
},
age: {
type: Number,
min: 1,
max: 50,
},
owner: {
name: String,
address: [String], // тип - масив рядків
birthday: Date,
},
});
Якщо ми спробуємо додати некоректні дані до БД, то запит на додавання поверне помилку.
Після цього необхідно створити модель, використовуючи схему:
const Cat = mongoose.model('cat', cats);
Перший параметр у методі mongoose.model
вказує на назву моделі, а другий
параметр - власне схема.
Далі можна створювати об'єкти для цієї моделі:
const cat = new Cat({
nickname: 'Barsik',
age: 1,
});
Для збереження об'єкта в базі викликається метод save
. Він визначений для всіх
створюваних моделей та зберігає поточний об'єкт у базу даних. Метод повертає
результат, об'єкт типу Document
, який представляє конкретний документ
що зберігається в колекції.
const result = cat.save();
console.log('Кіт збережений у базу! ', result);
Індекси
Якщо поле часто використовується при пошуку документів йому можна призначити індекс. Індексування полів дозволяє швидше шукати по цим полям. Індекс до поля можна додати двома способами.
Перший визначити у самій схемі
const cats = new Schema({
nickname: { type: String, index: 1 },
age: Number,
});
Або викликавши метод index
у самій схемі
const cats = new Schema({
nickname: String,
age: Number,
});
cats.index({ nickname: 1 });
Унікальні поля
Значення поля можна зробити унікальним. Це означає, що в інших документах
колекції не може бути такого поля з таким же значенням. Наприклад, логічно
зробити поле emal
, для схеми, яка описує користувача, унікальним. Для цього
треба у схемі, при визначенні поля, додати властивість unique
const user = new Schema({
username: String,
email: { type: String, unique: true },
});
Обов'язкові поля
Якщо під час створення нового документа не вказати поле, об'єкт буде створено без
цього поля. Деякі поля повинні обов'язково бути присутніми на новоствореному
об'єкті Document. Наприклад, теж ім'я користувача та email, у документі повинні
бути обов'язковими, нам можливо доведеться надсилати листи користувачеві на
відновлення паролю тощо. За обов'язкове поле відповідає властивість required
const user = new Schema({
username: { type: String, required: true },
email: { type: String, unique: true, required: true },
});
Методи у об'єкта схеми
У схемах, які визначає модуль Mongoose, існує можливість додавати
методи. Це дає можливість викликати заздалегідь визначені методи, використовуючи
об'єкт типу Document. Щоб додати метод до об'єкту типу Schema
треба
призначити функцію для властивості Schema.methods
. Всередині функції доступ до об'єкту
схеми відбувається за посиланням this
. Типовий приклад використання – це створення
функції, яка повертає повне ім'я користувача, шифрує пароль користувача
і т.д.
const user = new Schema({
firstName: String,
lastName: String,
});
user.methods.fullName = function () {
return `${this.firstName} ${this.lastName}`;
};
Отримавши потім екземпляр документа з бази, ми можемо викликати в нього функцію
fullName()
яка повертає повне ім'я та прізвище користувача
Основні операції з даними в Mongoose.
Створення документів
Крім розглянутого методу save()
також можна використати метод від моделі
об'єкта Cat.create()
. Першим параметром методу передається об'єкт для
збереження.
Cat.create({
nickname: 'Barsik',
age: 1,
});
Отримання даних
Для отримання даних можна використати методи.
find([query], [options]);
Встановлює операцію пошуку, яка повертає масив об'єктів типу Document, які збігаються із запитом
findOne([query], [options]);
Встановлює операцію пошуку одного документа, що повертає перший об'єкт Document, який збігається із запитом
Видалення даних
Для видалення застосовуються наступні методи
remove([query], [options]);
Встановлює операцію видалення, під час якої з колекції видаляються всі об'єкти, що збігаються із запитом
findOneAndRemove([query], [options]);
Встановлює операцію пошуку та видалення, під час якої з колекції видаляється перший же документ, що збігається із запитом
Зміна даних
update([query], [update], [options]);
Встановлює операцію поновлення, в ході якої в колекції оновлюються всі документи, що збігаються із запитом.
findOneAndUpdate([query], [update], [options]);
Встановлює операцію пошуку та оновлення, під час якої в колекції оновлюється перший же документ, що збігається із запитом.