MongoDB — это кроссплатформенная база данных NoSQL с открытым исходным кодом, используемая многими современными
В этом руководстве для начинающих я покажу, как установить Mongo, а затем начать использовать его для хранения и запроса данных. Я также рассмотрю, как взаимодействовать с базой данных Mongo из программы Node, а также попутно выделю некоторые различия между Mongo и традиционной реляционной базой данных (такой как MySQL).
Что такое MongoDB?
MongoDB — это
MongoDB также является базой данных без схемы, поэтому нам не нужно указывать количество или тип столбцов перед вставкой наших данных.
Вот пример того, как может выглядеть документ MongoDB:
{
_id: ObjectId (3da252d3902a),
type: «Tutorial»,
title: «An Introduction to MongoDB»,
author: «Manjunath M»,
tags: [ «mongodb», «compass», «crud» ],
categories: [
{
name: «javascript»,
description: «Tutorialss on
},
{
name: «databases»,
description: «Tutorialss on different kinds of databases and their management»
},
],
content: «MongoDB is a
}
Как видите, в документе есть ряд полей (typeи т. д title.), в которых хранятся значения («Учебник», «Введение в MongoDB» и т. д.). Эти значения могут содержать строки, числа, массивы, массивы вложенных документов (например, categoriesполе), геокоординаты и прочее.
Имя _idполя зарезервировано для использования в качестве первичного ключа. Его значение должно быть уникальным в коллекции, оно неизменяемо и может относиться к любому типу, кроме массива.
Совет: для тех, кто интересуется, что означает «подобный JSON», внутри Mongo используется
Как вы могли догадаться, документ в базе данных NoSQL соответствует строке в базе данных SQL. Группа документов вместе называется коллекцией, что является примерно синонимом таблицы в реляционной базе данных.
Вот таблица, суммирующая различные термины:
База данных База данных
Таблица Коллекция
Ряд Документ
Столбец Поле
Показатель Показатель
Если вы начинаете новый проект и не уверены, что выбрать: Mongo или реляционную базу данных, такую как MySQL, сейчас самое время прочитать наше руководство SQL vs NoSQL: как выбрать.
С учетом сказанного давайте продолжим и установим MongoDB.
Установка MongoDB
Примечание. Если вы просто хотите следовать этому руководству, не устанавливая
MongoDB поставляется в различных редакциях. Нас интересует MongoDB Community Edition.
На домашней странице проекта есть отличная документация по установке Mongo, и я не буду пытаться воспроизвести ее здесь. Скорее предложу вам ссылки на инструкции для каждой из основных операционных систем:
Установите MongoDB Community Edition в Windows
Установите MongoDB Community Edition на macOS
Установите MongoDB Community Edition на Ubuntu
Если вы используете версию Linux, отличную от Ubuntu, вы можете посетить эту страницу для получения инструкций по установке для других дистрибутивов. MongoDB также обычно доступен через официальные каналы программного обеспечения Linux, но иногда это приводит к использованию устаревшей версии.
Конфигурация после установки
После того, как вы установили MongoDB для своей системы, вы можете столкнуться с этой ошибкой:
dbpath (/data/db) does not exist.
Create this directory or give existing directory in —dbpath.
See http://dochub.mongodb.org/core/startingandstoppingmongo
Это означает, что Mongo не может найти (или получить доступ) каталог, который он использует для хранения своих баз данных. Это довольно легко исправить:
sudo mkdir -p /data/db
sudo chown -R `id -un` /data/db
Первая команда создает data/dbкаталог. Второй устанавливает разрешения, чтобы Mongo мог писать в этот каталог.
Установите графический интерфейс компаса
В этом руководстве мы будем использовать командную строку, но MongoDB также предлагает инструмент под названием Compass для подключения к вашим базам данных и управления ими с помощью графического интерфейса.
Если вы работаете в Windows, Compass можно установить как часть основной установки Mongo (просто выберите соответствующую опцию в мастере). В противном случае вы можете скачать Compass для своей ОС здесь.
Вот как это выглядит:
Графический интерфейс компаса Mongo DB
Оболочка Монго
Мы можем протестировать нашу установку, открыв оболочку Mongo. Вы можете сделать это, открыв окно терминала и набрав mongo.
Примечание. Предполагается, что это
Если вы получили сообщение Error: couldn’t connect to serverоб ошибке, вам нужно будет запустить сервер Mongo (во втором окне терминала) с помощью команды mongod.
Как только вы окажетесь в оболочке Mongo, введите, db.version () чтобы увидеть версию MongoDB, которую вы используете. На момент написания это должно выводить 4.2.2.
Обратите внимание, что вы можете выйти из оболочки Mongo, запустив quit () демон Mongo, нажав Ctrl+ Cв любое время.
Теперь давайте познакомимся с некоторыми основами MongoDB.
Основные операции с базой данных
Войдите в оболочку Mongo, если вы еще этого не сделали (введя mongoв терминал):
[mj@localhost ~]$ mongo
MongoDB shell version v4.2.2
connecting to: mongodb: //127.0.0.1:27017/? compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { «id»: UUID («
MongoDB server version: 4.2.2
Начнем с создания базы данных для работы. Для создания базы данных в MongoDB есть use DATABASE_NAMEкоманда:
> use exampledb
switched to db exampledb
Чтобы отобразить все существующие базы данных, попробуйте show dbs:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
Нет в exampledbсписке, потому что нам нужно вставить хотя бы один документ в базу данных. Чтобы вставить документ, вы можете использовать db.COLLECTION_NAME.insertOne ({«key»:"value"}). Вот пример:
> db.users.insertOne ({name: «Bob»})
{
«acknowledged»: true,
«insertedId»: ObjectId («5a52c53b223039ee9c2daaec»)
}
MongoDB автоматически создает новую usersколлекцию и вставляет документ с парой
Теперь мы должны увидеть нашу базу данных:
>show dbs
admin 0.000GB
config 0.000GB
exampledb 0.000GB
local 0.000GB
Точно так же вы можете подтвердить, что коллекция была создана с помощью show collectionsкоманды:
> show collections
users
Мы создали базу данных, добавили коллекцию с именем usersи вставили в нее документ. Теперь попробуем сбросить. Чтобы удалить существующую базу данных, используйте dropDatabase () команду, как показано ниже:
>db.dropDatabase ()
{ «dropped»: «exampledb», «ok»: 1 }
show dbsподтверждает, что база данных действительно была удалена:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
Дополнительные сведения об операциях с базой данных см. на справочной странице MongoDB по командам базы данных.
Управление пользователями
К настоящему времени вы, вероятно, заметили, что MongoDB не поставляется с
Хотя отсутствие необходимости указывать имя пользователя и пароль удобно для разработки, это то, что вы должны изменить при использовании Mongo в производственной среде.
Вот шаги для создания пользователя базы данных с полными правами чтения/записи:
Убедитесь, что вы запустили сервер Mongo без
Откройте оболочку, набрав mongo.
Из оболочки добавьте пользователя с readWriteролью в exampledbбазу данных. Это предложит вам ввести пароль. Очевидно, замените «manjunath» на желаемое имя пользователя:
js
use exampledb
db.createUser (
{
user: «manjunath»,
pwd: passwordPrompt (),
roles: [ { role: «readWrite» ]
}
)
Выйдите из оболочки Mongo.
Выключите сервер Mongo, затем перезапустите его с помощью mongod —auth. Клиенты, которые подключаются к этому экземпляру, теперь должны аутентифицировать себя.
Снова откройте оболочку следующим образом: mongo —authenticationDatabase «exampledb» -u «manjunath» -p. Теперь вам будет предложено ввести пароль.
Для получения дополнительной информации обратитесь к документации проекта по включению контроля доступа.
Как вы, возможно, уже знаете, аббревиатура CRUD означает создание, чтение, обновление и удаление. Это четыре основные операции с базой данных, которых нельзя избежать при создании приложения. Например, любое современное приложение будет иметь возможность создать нового пользователя, прочитать данные пользователя, обновить информацию о пользователе и, при необходимости, удалить учетную запись пользователя. Давайте сделаем это на уровне базы данных, используя MongoDB.
Создать операцию
Создание аналогично вставке документа в коллекцию. В предыдущем разделе мы вставили один документ, используя db.collection.insertOne () синтаксис. Есть еще один метод db.collection.insertMany (), который позволяет вставлять сразу несколько документов. Вот синтаксис:
> db.collection.insertMany ([
Давайте создадим usersколлекцию и заполним ее некоторыми реальными пользователями:
> use exampledb
> db.users.insertMany ([
{ name: «Tom», age:15, email: «tom@example.com» },
{ name: «Bob», age:35, email:«bob@example.com» },
{ name: «Kate», age: 27, email: «kate@example.com» },
{ name: «Katherine», age:65, email:"katherine@example.com"}
])
{
«acknowledged»: true,
«insertedIds»: [
ObjectId («5e25bb58ba0cf16476aa56ff»),
ObjectId («5e25bb58ba0cf16476aa5700»),
ObjectId («5e25bb58ba0cf16476aa5701»),
ObjectId («5e25bb58ba0cf16476aa5702»)
]
}
Метод insertManyпринимает массив объектов, а взамен мы получаем массив ObjectIds.
Операция чтения
Операция чтения используется для извлечения документа или нескольких документов из коллекции. Синтаксис операции чтения следующий:
> db.collection.find (query, projection)
Чтобы получить все пользовательские документы, вы можете сделать это:
> db.users.find ().pretty ()
{
«_id»: ObjectId («5e25bb58ba0cf16476aa56ff»),
«name»: «Tom»,
«age»: 15,
«email»: «tom@example.com»
}
{
«_id»: ObjectId («5e25bb58ba0cf16476aa5700»),
«name»: «Bob»,
«age»: 35,
«email»: «bob@example.com»
}
{
«_id»: ObjectId («5e25bb58ba0cf16476aa5701»),
«name»: «Kate»,
«age»: 27,
«email»: «kate@example.com»
}
{
«_id»: ObjectId («5e25bb58ba0cf16476aa5702»),
«name»: «Katherine»,
«age»: 65,
«email»: «katherine@example.com»
}
Это соответствует SELECT * FROM USERSзапросу для базы данных SQL.
Это prettyметод курсора, и есть много других. Вы можете связать эти методы, чтобы изменить запрос и документы, возвращаемые запросом.
Возможно, вам нужно отфильтровать запросы, чтобы вернуть подмножество коллекции — например, найти всех пользователей младше 30 лет. Вы можете изменить запрос следующим образом:
> db.users.find ({ age: { $lt: 30 } })
{ «_id»: ObjectId («5e25bb58ba0cf16476aa56ff»), «name»: «Tom», «age»: 15, «email»: «tom@example.com» }
{ «_id»: ObjectId («5e25bb58ba0cf16476aa5701»), «name»: «Kate», «age»: 27, «email»: «kate@example.com» }
В этом примере $lt— оператор фильтра запроса, который выбирает документы, ageзначение поля которых меньше 30. Доступно множество фильтров сравнения и логических запросов. Весь список можно посмотреть в документации по селекторам запросов.
Примечание. В Mongo вы можете реплицировать likeзапрос SQL с помощью регулярного выражения. Например, SELECT * FROM users WHERE name LIKE 'Kat%'переводится на db.users.find ({ name: /Kat. */ }).
Операция обновления
Операция обновления изменяет документы в коллекции. Подобно операции создания, MongoDB предлагает различные методы обновления документа. Например:
db.collection.updateOne (
db.collection.updateMany (
Если вам нужно добавить дополнительное поле, скажем, registrationко всем существующим документам в коллекции, вы можете сделать
> db.users.updateMany ({}, {$set: { registration: «incomplete»}})
{ «acknowledged»: true, «matchedCount»: 4, «modifiedCount»: 4 }
Первый аргумент — это пустой объект, потому что мы хотим обновить все документы в коллекции. Это $setоператор обновления, который устанавливает значение поля с указанным значением. Вы можете убедиться, что дополнительное поле было добавлено с помощью db.users.find ().
Чтобы обновить значение документов, соответствующих определенным критериям, updateMany () принимает объект фильтра в качестве первого аргумента. Например, вы можете перезаписать значение registrationto completeдля всех пользователей старше 18 лет. Вот что вы можете сделать:
> db.users.updateMany (
{age: { $gt: 18} },
{$set: { registration: «complete»}
})
{ «acknowledged»: true, «matchedCount»: 3, «modifiedCount»: 3 }
Чтобы обновить регистрационные данные одного пользователя, вы можете сделать это:
> db.users.updateOne (
{email: «tom@example.com» },
{$set: { registration: «complete»}
})
{ «acknowledged»: true, «matchedCount»: 1, «modifiedCount»: 1 }
Удалить операцию
Операция удаления удаляет документ из коллекции. Чтобы удалить документ, вы можете использовать db.collection.deleteOne (
Чтобы удалить документы по определенным критериям, вы можете использовать операторы фильтра, которые мы использовали для операции чтения и обновления:
> db.users.updateOne (
{email: «tom@example.com» },
{$set: { status: «dormant»}
})
{ «acknowledged»: true, «matchedCount»: 1, «modifiedCount»: 1 }
> db.users.deleteMany ({ status: { $in: [ «dormant», «inactive» ] } })
{ «acknowledged»: true, «deletedCount»: 1 }
При этом удаляются все документы со статусом «спящий» или «неактивный».
Проверка схемы
Ранее в этом руководстве, когда я говорил, что Mongo — это база данных без схемы, я несколько упрощал.
Он не содержит схемы, поскольку нам не нужно указывать количество или тип столбцов перед вставкой наших данных. Однако также можно определить схему JSON и использовать ее для обеспечения соблюдения правил проверки наших данных.
Давайте создадим validatedUsersколлекцию, где мы можем использовать validatorконструкцию, чтобы указать, что a nameявляется обязательным и что emailполе соответствует определенному шаблону:
> db.createCollection («validatedUsers», {
validator: {
$jsonSchema: {
required: [ «name», «email» ],
properties: {
name: {
bsonType: «string»,
description: «must be a string and is required»
},
email: {
bsonType: «string»,
pattern: «^. +\@. +$»,
description: «must be a valid email and is required»
}
}
}
}
})
{ «ok»: 1 }
Теперь, если мы попытаемся вставить неверные данные, мы получим ошибку проверки:
> db.validatedUsers.insertOne ({ name: «Jim», email: «
«index»: 0,
«code»: 121,
«errmsg»: «Document failed validation»,
«op»: {
«_id»: ObjectId («5e280e5847eb18010666530c»),
«name»: «Jim»,
«email»: «
}
}):
WriteError ({
«index»: 0,
«code»: 121,
«errmsg»: «Document failed validation»,
«op»: {
«_id»: ObjectId («5e280e5847eb18010666530c»),
«name»: «Jim»,
«email»: «
}
})
WriteError@src/mongo/shell/bulk_api.js:458:48
mergeBatchResults@src/mongo/shell/bulk_api.js:855:49
executeBatch@src/mongo/shell/bulk_api.js:919:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1163:21
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:264:9
@ (shell):1:1
Подробнее о проверке схемы можно прочитать в документации проекта.
Обзор драйверов MongoDB
Чтобы приложение могло взаимодействовать с сервером MongoDB, вы должны использовать клиентскую библиотеку, называемую драйвером. Драйвер находится поверх сервера базы данных и позволяет вам взаимодействовать с базой данных с помощью API драйвера. MongoDB имеет официальные и сторонние драйверы для всех популярных языков и сред.
Самые популярные драйверы для Node.js включают собственный драйвер MongoDB и Mongoose. Я кратко обсужу оба из них здесь.
Драйвер MongoDB Node.js
Это официальный драйвер MongoDB для Node.js. Драйвер может взаимодействовать с базой данных с помощью обратных вызовов, промисов или async... await.
Вы можете установить его так:
npm install mongod
В приведенном ниже примере показано, как подключить драйвер к серверу и вывести список всех документов в usersколлекции.
Примечание. Если вы подключились к серверу Mongo с помощью имени и пароля, вам необходимо указать эти данные в своем коде.
Имя и пароль
Если вы подключились к серверу Mongo, используя имя и пароль, вам нужно будет указать эти данные в своем коде.
const MongoClient = require ('mongodb’).MongoClient;
const url = 'mongodb: //localhost:27017/exampledb’;
// With authentication:
// const url = 'mongodb: //
// Further reading: https://docs.mongodb.com/manual/reference/connection-string/
(async () => {
let client;
try {
client = await MongoClient.connect (url, {
useNewUrlParser: true,
useUnifiedTopology: true
}) ;
const db = client.db ('exampledb’) ;
const collection = db.collection ('users’) ;
const users = await collection.find ().toArray () ;
console.log (users) ;
} catch (err) {
console.log (err.stack) ;
}
if (client) {
client.close () ;
}
}) () ;
MongoClient.connectВозвращает обещание. Любая ошибка перехватывается catchблоком, и любые действия с базой данных проходят внутри tryблока. Если вы просмотрите документацию по драйверу Mongo, вы увидите, что API очень похож на то, что мы использовали в оболочке.
Водитель мангуста
Другой популярный драйвер Node.js для MongoDB — Mongoose. Mongoose построен на основе официального драйвера MongoDB. Когда Mongoose был выпущен, у него было множество функций, которых не было в родном драйвере MongoDB. Одной из важных особенностей была возможность определить структуру схемы, которая будет отображаться в коллекции базы данных. Однако последние версии MongoDB приняли некоторые из этих функций в виде схемы JSON и проверки схемы.
Помимо схемы, другие интересные функции Mongoose включают модели, валидаторы и промежуточное ПО, метод заполнения, плагины и так далее. Вы можете прочитать больше об этом в документации Mongoose.
Вы можете установить Mongoose следующим образом:
npm install mongoose
Вот эквивалент предыдущего примера для Mongoose:
const mongoose = require ('mongoose’) ;
async function run () {
await mongoose.connect ('mongodb: //localhost:27017/exampledb’, {
useNewUrlParser: true,
useUnifiedTopology: true
}) ;
const userSchema = new mongoose.Schema ({ name: String, age: String, email: String }) ;
const User = mongoose.model ('User’, userSchema) ;
const users = await User.find () ;
console.log (users) ;
mongoose.connection.close () ;
}
run ().catch (error => console.log (error.stack));
В Mongoose все начинается с aa Schema. Каждая схема сопоставляется с коллекцией MongoDB и определяет форму документов в этой коллекции.
Вывод
MongoDB — это популярное решение для баз данных NoSQL, которое соответствует современным требованиям разработки. В этом руководстве мы рассмотрели основы MongoDB, оболочки Mongo и некоторых популярных доступных драйверов. Мы также изучили общие операции с базами данных и действия CRUD в оболочке Mongo. Теперь пришло время отправиться и попробовать то, что мы здесь рассмотрели, и многое другое. Если вы хотите узнать больше, я рекомендую создать REST API с MongoDB и Node, чтобы ознакомиться с общими операциями и методами базы данных.