Обработка ошибок MongoDB

MongoDBBeginner
Практиковаться сейчас

Введение

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

Подключение к MongoDB и обработка ошибок

Ошибки подключения являются распространенной проблемой при работе с любой базой данных. Они могут возникать по нескольким причинам, таким как неправильный адрес сервера, проблемы с сетью или незапущенный сервер базы данных. На этом шаге вы научитесь выявлять ошибку подключения и затем успешно подключаться.

Сначала попытайтесь подключиться к экземпляру MongoDB на порту, на котором он не запущен. Порт по умолчанию для MongoDB — 27017. Мы попытаемся подключиться к порту 27018.

Выполните следующую команду в вашем терминале:

mongosh "mongodb://localhost:27018"

Эта команда завершится ошибкой, поскольку оболочка не сможет найти сервер MongoDB по указанному адресу. Вывод будет выглядеть примерно так:

MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27018

MongoNetworkError явно указывает на сбой подключения. Часть ECONNREFUSED сообщает вам, что целевая машина активно отклонила соединение, что обычно означает, что никакой сервис не прослушивает этот порт.

Теперь давайте подключимся к правильному порту. Служба MongoDB была запущена для вас на этапе настройки. Чтобы подключиться к ней, выполните команду mongosh без аргументов. Это приведет к использованию строки подключения по умолчанию mongodb://127.0.0.1:27017.

mongosh

После успешного подключения вы увидите приветственное сообщение и приглашение test>, указывающее на то, что вы подключены к базе данных test по умолчанию.

Current Mongosh Log ID: ...
Connecting to:          mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.2.6
Using MongoDB:          8.0.0
Using Mongosh:          2.2.6
...
test>

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

Обработка ошибок дублирования ключей

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

Вы уже должны находиться в оболочке mongosh из предыдущего шага. Сначала переключитесь на новую базу данных с именем errorlab. База данных создается автоматически при первом сохранении в нее данных.

use errorlab

Далее создайте уникальный индекс по полю email в новой коллекции users. Эта команда сообщает MongoDB, что каждый документ в коллекции users должен иметь уникальное значение для поля email.

db.users.createIndex({ email: 1 }, { unique: true });

Вывод подтверждает успешное создание индекса.

{
  "numIndexesBefore": 1,
  "numIndexesAfter": 2,
  "createdCollectionAutomatically": true,
  "ok": 1
}

Теперь вставьте документ в коллекцию users. Эта операция будет успешной, поскольку коллекция пуста, а адрес электронной почты уникален.

db.users.insertOne({ name: "John Doe", email: "john@example.com" });

Вы увидите сообщение с подтверждением и идентификатором вставленного документа:

{
  "acknowledged": true,
  "insertedId": ObjectId("...")
}

Далее попытайтесь вставить другой документ с точно таким же адресом электронной почты.

db.users.insertOne({ name: "Jane Doe", email: "john@example.com" });

На этот раз операция завершается неудачно. MongoDB возвращает MongoBulkWriteError с конкретным кодом ошибки E11000, который означает ошибку дублирования ключа. Это ожидаемое поведение для защиты целостности данных.

MongoServerError: E11000 duplicate key error collection: errorlab.users index: email_1 dup key: { email: "john@example.com" }

Устранение дубликатов ключей с помощью Upsert

Предотвращение дубликатов — это хорошо, но иногда требуется обновить запись, если она существует, или создать ее, если нет. Эта логика "обновить или вставить" является распространенным требованием. MongoDB предоставляет удобный способ сделать это с помощью опции upsert.

Попробуем обновить пользователя с адресом электронной почты john@example.com. Мы будем использовать метод updateOne с опцией upsert, установленной в true.

db.users.updateOne(
  { email: "john@example.com" },
  { $set: { name: "John Doe Updated", lastUpdated: new Date() } },
  { upsert: true }
);

Вывод показывает, что один документ был найден и изменен. upsertedId равен null, потому что существующий документ был обновлен, а не вставлен новый.

{
  "acknowledged": true,
  "matchedCount": 1,
  "modifiedCount": 1,
  "upsertedId": null
}

Теперь выполним аналогичную команду для пользователя, которого еще нет, jane@example.com.

db.users.updateOne(
  { email: "jane@example.com" },
  { $set: { name: "Jane Doe", lastUpdated: new Date() } },
  { upsert: true }
);

На этот раз вывод показывает, что matchedCount равен 0, но был создан новый документ, на что указывает upsertedId.

{
  "acknowledged": true,
  "matchedCount": 0,
  "modifiedCount": 0,
  "upsertedId": ObjectId("...")
}

Чтобы проверить результаты, вы можете выполнить запрос к коллекции, чтобы увидеть все документы. Метод pretty() форматирует вывод для удобства чтения.

db.users.find().pretty();

Вывод отобразит оба документа: документ Джона с обновленным именем и вновь созданный документ Джейн. Опция upsert предоставляет мощный и атомарный способ обработки сценариев "создать или обновить".

Обработка ошибок запросов и валидации

Ошибки также могут возникать при выполнении запросов к данным или когда вставляемые данные не соответствуют предопределенным правилам. В этом шаге вы изучите ошибку синтаксиса запроса и ошибку валидации данных.

Сначала посмотрим, что произойдет при использовании несуществующего оператора запроса. Это распространенная опечатка.

db.users.find({ name: { $invalidOperator: "John" } });

MongoDB немедленно вернет ошибку, поскольку не распознает $invalidOperator.

MongoServerError[BadValue]: unknown operator: $invalidOperator

Далее изучим более мощную функцию: валидацию схемы. Вы можете определить правила, которым должны следовать документы при вставке или обновлении в коллекции. Создадим новую коллекцию products с валидатором, который требует наличия поля name (строка) и price (число).

db.createCollection("products", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "price"],
      properties: {
        name: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        price: {
          bsonType: "number",
          description: "must be a number and is required"
        }
      }
    }
  }
});

Теперь попытаемся вставить документ, который нарушает эту схему, предоставив price в виде строки вместо числа.

db.products.insertOne({ name: "Laptop", price: "1200" });

Операция завершится с ошибкой MongoBulkWriteError. Сообщение Document failed validation четко указывает причину, предотвращая попадание некорректных данных в вашу базу данных.

MongoServerError: Document failed validation
...

Наконец, вставим допустимый документ, соответствующий схеме.

db.products.insertOne({ name: "Laptop", price: 1200 });

Эта операция будет успешной, поскольку документ является допустимым.

{
  "acknowledged": true,
  "insertedId": ObjectId("...")
}

Валидация схемы — это мощный инструмент для обеспечения согласованности данных непосредственно в базе данных.

Резюме

В этой лабораторной работе вы научились обрабатывать несколько распространенных типов ошибок MongoDB с помощью оболочки mongosh. Вы начали с выявления и устранения ошибки подключения. Затем вы обеспечили целостность данных, создав уникальный индекс для предотвращения ошибок дублирования ключей. Вы также узнали, как использовать опцию upsert для корректной обработки логики "обновить или вставить". Наконец, вы изучили ошибки синтаксиса запросов и использовали валидацию схемы для предотвращения сохранения недопустимых данных в вашей базе данных. Эти фундаментальные навыки обработки ошибок необходимы для создания надежных и устойчивых приложений с использованием MongoDB.