Как применить правила проверки схемы в коллекции

Краткое введение

MongoDB — очень популярная бесплатная кроссплатформенная документоориентированная база данных с открытым исходным кодом. Это база данных NoSQL, основанная на документах в формате JSON. Базы данных на основе документов либо не содержат схемы, либо обеспечивают определенный уровень гибкости, определяя схемы с помощью правил проверки схемы.

Для тех, кто пришел из мира СУБД, где структура таблицы характеризуется столбцами со строго определенными свойствами (тип, размер и т. д.), возможность определения схем может оказаться весьма полезной опцией.

Как правило, мы можем думать, что объект базы данных MongoDB похож на схему СУБД, содержащую таблицы, представления и другие объекты СУБД. Соответственно, коллекция MongoDB аналогична таблице, а документ MongoDB можно рассматривать как строку таблицы.

База данных MongoDB может группировать коллекции, коллекция содержит документы, а документ состоит из ряда объектов пар ключ-значение и даже из других документов.

Цель этого поста — продемонстрировать, как мы можем применять некоторые правила проверки схемы в коллекции. Для этого необходимо создать пример базы данных MongoDB с коллекцией MongoDB.

Предпосылки и предположения

Здесь вы можете получить обзор.

Предполагается, что у вас есть доступный и работающий экземпляр MongoDB. Если у вас его нет, вы можете легко добиться этого, также используя Docker и официальный образ MongoDB Docker для запуска контейнера MongoDB. Подробнее читайте на https://www.mongodb.com/compatibility/docker.

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

Запустите Docker-контейнер MongoDB

Вы можете создать и запустить контейнер Docker с именем «mongodb», выполнив следующую команду:

docker run --name mongodb -p 27017:27017 -d mongo

После того, как вы создали контейнер, вы можете остановить и запустить его с помощью следующих команд соответственно:

docker stop mongodb
docker start mongodb

Кроме того, вы всегда можете проверить запущенные контейнеры с помощью следующего:

docker ps

Получите графический интерфейс MongoDB Compass и определите базу данных и коллекцию

Вы можете скачать GUI Compass по следующей ссылке: https://www.mongodb.com/try/download/compass

После того, как вы установите его, запустите его. Убедитесь, что контейнер mongodb запущен и работает, и создайте новое соединение, используя строку подключения, которая в нашем случае может быть следующей:

mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false

Затем, после успешного подключения к экземпляру докера MongoDB, вы можете создать новую базу данных и новую коллекцию. Назовите их «управление билетами» и «пользователи» соответственно.

Коллекция «users» будет хранить пользовательские документы, и документы должны быть проверены нашими правилами проверки.

Определение свойств документа MongoDB

Как мы уже говорили, документ MongoDB представляет собой упорядоченный набор пар ключ-значение. Ключевое отличие от РСУБД заключается в том, что документ MongoDB может хранить документы любого размера пар ключ-значение, а также вложенные документы.

Однако в нашем случае мы хотим, чтобы коллекция «users» содержала документы строго с одинаковыми свойствами (ключами). Это аналогично полям (столбцам) таблицы в СУБД. Так, например, мы хотим, чтобы каждый документ имел точно такие же свойства/поля.

монго _id

Прежде чем мы определим поля нашей коллекции «пользователей», стоит упомянуть, что MongoDB автоматически генерирует специальное свойство/поле _id каждый раз, когда новый документ вставляется в коллекцию.

_id — это специальный тип данных для MongoDB. Фактически это объект MongoDB (ObjectID) типа BSON размером 12 байт. 12-байтовый _id состоит из следующего:

  • 4 байта, представляющие секунды с эпохи Unix
  • 3 байта, специфичные для хоста — идентификатор машины
  • 2 байта идентификатора процесса и
  • 3 байта, представляющие счетчик, начиная со случайного значения

Даже тот факт, что автоматически сгенерированный _id на самом деле не является стандартным UUID. Поля _id можно считать уникальными. Они упорядочены, и их можно использовать как первичный ключ нашей коллекции.

После этого это примерный список полей для коллекции «users»:

_id
username,
password,
email,
registrationdate,
confirmed,
cancelled,
typeid,
countryid

Цель состоит в том, чтобы гарантировать (ну, насколько это возможно), что все документы, предназначенные для вставки в коллекцию «users», должны состоять из этих полей.

Правила проверки схемы MongoDB

Чтобы все документы соответствовали указанным выше полям, мы будем использовать определенную схему MongoDB. Вы можете подумать, что схема MongoDB — это не что иное, как набор правил для свойств документа (ключей) и значений. Эти правила действуют для каждой коллекции отдельно. Правила должны соблюдаться (= проверены) во время вставки или обновления каждого документа в конкретной коллекции.

Такой набор правил должен быть определен с помощью файла JSON в соответствии со стандартами BSON.

Мы не будем вдаваться в подробности здесь, но вы можете узнать больше о схеме MongoDB и о том, как она работает, используя официальную документацию. Например, вы можете перейти по ссылкам ниже:

После краткого вступления, приведенного выше, пришло время определить нашу схему проверки MongoDB. Краткое изложение того, что мы на самом деле хотим определить, приведено ниже:

  • Поля: username, email и password должны присутствовать в каждом документе (обязательны).
  • Поля: username, email и password должны иметь строковый тип, а длина их строк должна быть между минимальным и максимальным пределами.
  • Поле email должно соответствовать определенному шаблону регулярного выражения.
  • Поле: registrationdate должно иметь тип даты.
  • Поля: confirmed и canceled должны быть типа bool (логическое значение: true или false).
  • Поля typeid и countryid должны быть типа int (целое число), а их значения должны быть между минимальным и максимальным числом.

Мы определяем наши правила с помощью различных методов через mongo shell CLI или mongosh CLI, но, поскольку мы уже создали нашу коллекцию пользователей в Compass, использование графического интерфейса Compass кажется удобным способом.

Итак, выберите коллекцию «пользователи», перейдите на вкладку «Проверка» и поместите свою схему JSON (оставьте для параметров «Действие проверки» и «Уровень проверки» значения «ОШИБКА» и «СТРОГО» соответственно). Ниже приведен пример правил проверки, которые мы будем использовать:

Схема проверки коллекции mongodb (compass)

Проверьте правила проверки через CLI Mongosh и Mongo Shell.

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

По умолчанию mongosh подключен к тестовой базе данных, как вы можете видеть выше. Итак, переключитесь на базу данных tickets-management и перейдите к правилам проверки с помощью функции db.getCollectionInfos():

Похоже, мы не можем углубиться и посмотреть/проверить «свойства» объектов с помощью встроенного монгоша.

Однако мы можем перейти в оболочку контейнера:

docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED        STATUS       PORTS                      NAMES
11b9a599c13e   mongodb   "docker-entrypoint.s…"   3 months ago   Up 4 hours   0.0.0.0:27017->27017/tcp   mongodb
. . .
docker exec -it mongodb bash
root@11b9a599c13e:/#

И запустите монгош изнутри, используя эти команды:

root@11b9a599c13e:/# 
root@11b9a599c13e:/# mongosh
Current Mongosh Log ID:    6229dc064130345cc3d542bf
Connecting to:        mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000
Using MongoDB:        5.0.5
Using Mongosh:        1.1.6
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
You can opt-out by running the disableTelemetry() command.
------
   The server generated these startup warnings when booting:
   2022-03-10T05:41:44.202+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
   2022-03-10T05:41:45.856+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
------
Warning: Found ~/.mongorc.js, but not ~/.mongoshrc.js. ~/.mongorc.js will not be loaded.
  You may want to copy or rename ~/.mongorc.js to ~/.mongoshrc.js.
test>

Затем мы можем переключиться на базу данных ticket-management и выполнить db.collectionInfos(), чтобы получить информацию о правилах проверки для коллекции «users», как вы можете видеть ниже:

На этот раз наши правила проверки четко представлены.

В качестве альтернативы мы можем запустить только CLI mongo (не mongosh), как показано ниже:

root@11b9a599c13e:/# mongo
MongoDB shell version v5.0.5
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("bb023c59-6160-461d-b022-4d88658fb890") }
MongoDB server version: 5.0.5
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    https://docs.mongodb.com/
Questions? Try the MongoDB Developer Community Forums
    https://community.mongodb.com
---
The server generated these startup warnings when booting: 
        2022-03-10T05:41:44.202+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
        2022-03-10T05:41:45.856+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).
        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.
        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
>

Обратите внимание, что оболочка mongo устарела и заменена mongosh.

Затем мы снова можем переключиться на базу данных ticket-management и выполнить db.collectionInfos(), чтобы получить такую ​​информацию для коллекции «users»:

Как вы можете видеть выше, результат почти такой же.

Проверьте наши правила проверки

После того, как мы определили наши правила проверки, мы можем использовать любой из доступных инструментов (GUI Compass, mongosh CLI, mongo CLI) и проверить, правильно ли они работают. Для этого мы можем попробовать вставить некоторые документы, которые не соответствуют требованиям правил проверки, и подтвердить их несостоятельность. Ниже приведены некоторые такие примеры, которые также можно использовать самостоятельно.

Использование монгоша

Попробуем вставить пустой документ:

Теперь давайте попробуем еще раз с документом с недействительным адресом электронной почты:

Вы можете продолжить попытки вставить документы с неверными значениями, например, используя значение поля typeid — значение 0, например, когда оно должно быть как минимум:

Использование компаса

Точно так же, пытаясь вставить документы, которые не соответствуют нашим правилам проверки, вы будете продолжать получать ошибки сбоя, такие как следующие:

Предостережения

Использование правил проверки MongoDB весьма полезно и избавляет нас от многих головных болей. Однако это не панацея. В качестве примера недостатка можно упомянуть невозможность определить уникальность с помощью полей, например, мы не можем предотвратить вставку (или обновление) документа со значением имени пользователя, которое уже существует в другом документе.

Другой пример: мы также не можем запретить вставку документов, в которых нет всех полей (кроме обязательных). И так далее.

Однако, как предполагает MongoDB, такие проблемы могут быть решены в нашей бизнес-логике в промежуточном программном обеспечении, но это тема другого поста. Итак, следите за обновлениями!

Вот и все!

Спасибо за чтение и удачного кодирования!