Вставка данных в MongoDB

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

Введение

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

Эта лабораторная работа посвящена операции "Создание" в рамках CRUD (Create, Read, Update, Delete - Создание, Чтение, Обновление, Удаление). Вы создадите простую базу данных книжного магазина с нуля, получив практический опыт выполнения основных задач управления данными в среде NoSQL. К концу работы вы будете иметь твердое представление о том, как эффективно добавлять и управлять данными в MongoDB.

Вставка одного документа

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

Сначала подключитесь к вашему локальному экземпляру MongoDB с помощью MongoDB Shell. Откройте терминал и выполните следующую команду:

mongosh

Вы увидите приглашение > , указывающее, что вы находитесь в MongoDB Shell и подключены к базе данных.

Далее переключитесь на новую базу данных с именем bookstore. Если база данных не существует, MongoDB создаст ее для вас при первом сохранении данных.

use bookstore

Вывод подтвердит, что вы переключились на базу данных bookstore.

switched to db bookstore

Теперь вставьте один документ в новую коллекцию с именем books. Коллекция — это группа документов MongoDB, примерно эквивалентная таблице в реляционной базе данных. Метод insertOne() добавляет один документ в коллекцию.

db.books.insertOne({
  title: "The Great Gatsby",
  author: "F. Scott Fitzgerald",
  year: 1925,
  genres: ["Classic", "Fiction"],
  stock: 10
});

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

{
  acknowledged: true,
  insertedId: ObjectId("652f8d3e111a2b3c4d5e6f78")
}

_id — это уникальный идентификатор, автоматически генерируемый MongoDB для каждого документа, гарантирующий, что каждый документ в коллекции может быть однозначно идентифицирован.

Вставка нескольких документов

Вставка документов по одному может быть неэффективной. Для одновременного добавления нескольких документов MongoDB предоставляет метод insertMany(). Это известно как операция пакетной вставки (bulk insert), которая сокращает количество сетевых обращений к базе данных.

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

Используйте метод insertMany(), передав ему массив объектов документов.

db.books.insertMany([
  {
    title: "1984",
    author: "George Orwell",
    year: 1949,
    genres: ["Dystopian", "Science Fiction"],
    stock: 15
  },
  {
    title: "To Kill a Mockingbird",
    author: "Harper Lee",
    year: 1960,
    genres: ["Classic", "Fiction"],
    stock: 5
  },
  {
    title: "Pride and Prejudice",
    author: "Jane Austen",
    year: 1813,
    genres: ["Romance", "Classic"],
    stock: 12
  }
]);

Вывод подтвердит, что операция была подтверждена, и перечислит значения _id для каждого из трех вставленных вами документов.

{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId("652f8e3e111a2b3c4d5e6f79"),
    '1': ObjectId("652f8e3e111a2b3c4d5e6f7a"),
    '2': ObjectId("652f8e3e111a2b3c4d5e6f7b")
  }
}

Чтобы убедиться, что документы были добавлены, вы можете подсчитать общее количество документов в коллекции.

db.books.countDocuments();

Результат должен быть 4, что соответствует одному документу из предыдущего шага и трем, которые вы только что добавили.

4

Запрос и проверка вставленных данных

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

Чтобы извлечь все документы из коллекции books, используйте метод find() без каких-либо аргументов.

db.books.find();

Эта команда выведет все четыре документа, находящиеся в вашей коллекции. Вывод может быть довольно объемным, но это хороший способ увидеть все сразу.

Чаще всего вам потребуется находить документы, соответствующие определенным критериям. Чтобы найти все книги, опубликованные до 1950 года, вы можете использовать фильтр запроса с оператором $lt (меньше чем).

db.books.find({ year: { $lt: 1950 } });

Этот запрос вернет документы для "The Great Gatsby", "1984" и "Pride and Prejudice".

Иногда вам нужны только определенные поля из документов, а не весь документ целиком. Это называется проекцией. Чтобы получить только title (название) и author (автор) всех книг в жанре "Classic", вы можете добавить документ проекции в качестве второго аргумента к find().

db.books.find({ genres: "Classic" }, { title: 1, author: 1, _id: 0 });

В документе проекции 1 означает "включить это поле", а 0 — "исключить это поле". По умолчанию поле _id всегда включается, поэтому мы явно исключаем его с помощью _id: 0.

Вывод будет представлять собой аккуратный список названий и авторов:

[
  { "title": "The Great Gatsby", "author": "F. Scott Fitzgerald" },
  { "title": "To Kill a Mockingbird", "author": "Harper Lee" },
  { "title": "Pride and Prejudice", "author": "Jane Austen" }
]

Обработка ошибок вставки с помощью уникального индекса

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

Убедимся, что в нашей коллекции не может быть двух книг с одинаковым названием. Для этого создадим уникальный индекс по полю title.

db.books.createIndex({ title: 1 }, { unique: true });

Вывод подтверждает имя созданного индекса.

title_1

Теперь, когда уникальный индекс установлен, давайте попробуем вставить документ с названием, которое уже существует в коллекции, например, "1984".

db.books.insertOne({
  title: "1984",
  author: "George Orwell",
  year: 1949,
  genres: ["Dystopian", "Science Fiction"],
  stock: 20
});

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

MongoBulkWriteException: E11000 duplicate key error collection: bookstore.books index: title_1 dup key: { title: "1984" }

В приложении вы бы обернули такие операции с базой данных в блок try...catch, чтобы корректно обрабатывать эти ошибки, а не вызывать сбой программы. Вы можете смоделировать это и в оболочке mongosh.

try {
  db.books.insertOne({
    title: "1984",
    author: "George Orwell"
  });
} catch (e) {
  print("Error inserting document:", e.message);
}

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

Обеспечение целостности данных с помощью проверки схемы

Хотя MongoDB известна своей гибкой схемой, вы можете обеспечить определенную структуру для ваших документов с помощью проверки схемы (schema validation). Это гарантирует, что все документы в коллекции соответствуют определенному набору правил, улучшая качество и согласованность данных.

На этом заключительном шаге вы добавите валидатор к коллекции books. Этот валидатор потребует, чтобы каждый документ имел поля title, author и year, а также будет обеспечивать соблюдение определенных типов данных и диапазонов для этих полей.

Используйте команду collMod (изменить коллекцию) для добавления валидатора.

db.runCommand({
  collMod: "books",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["title", "author", "year"],
      properties: {
        title: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        author: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        year: {
          bsonType: "int",
          minimum: 1000,
          maximum: 2024,
          description: "must be an integer between 1000 and 2024"
        }
      }
    }
  }
});

Вывод { ok: 1 } подтверждает, что валидатор был успешно применен.

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

db.books.insertOne({
  title: "The Hobbit",
  author: "J.R.R. Tolkien",
  year: 999
});

Вставка завершится неудачей, и MongoDB вернет сообщение об ошибке, объясняющее, что документ не прошел проверку.

MongoBulkWriteException: Document failed validation

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

Резюме

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

Вы также отработали запросы и проверку данных с помощью find() и countDocuments(). Самое главное, вы изучили два ключевых метода обеспечения целостности данных: создание уникального индекса для предотвращения дубликатов и реализацию проверки схемы (schema validation) для обеспечения согласованной структуры документов. Эти навыки являются основополагающими для создания надежных и устойчивых приложений с использованием MongoDB.