Работа с массивами MongoDB

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

Введение

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

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

Создание документов с полями-массивами

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

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

mongosh

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

use arraylab

Скрипт setup уже создал коллекцию students и вставил один документ. Теперь вы вставите новый документ для студента по имени "Alice Johnson". Этот документ будет иметь поле courses, которое является массивом строк.

db.students.insertOne({
    name: "Alice Johnson",
    age: 22,
    courses: ["Mathematics", "Computer Science", "Physics"]
})

Эта команда вставляет один документ в коллекцию students. Поле courses содержит массив из трех строковых элементов.

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

db.students.find().pretty()

Вы должны увидеть два документа: документ для "Bob Smith", созданный во время настройки, и документ "Alice Johnson", который вы только что добавили.

[
  {
    _id: ObjectId("..."),
    name: 'Bob Smith',
    grades: [ 95, 87, 92 ],
    activities: [ 'Chess Club', 'Debate Team' ]
  },
  {
    _id: ObjectId("..."),
    name: 'Alice Johnson',
    age: 22,
    courses: [ 'Mathematics', 'Computer Science', 'Physics' ]
  }
]

Добавление элементов в массив

После создания массивов распространенной задачей является добавление в них новых элементов. На этом этапе вы научитесь использовать оператор $push для добавления элементов в существующий массив.

Чтобы добавить один элемент в массив, используйте оператор $push в операции обновления. Давайте добавим новый курс, "Data Science", в список курсов Alice Johnson.

db.students.updateOne(
    { name: "Alice Johnson" },
    { $push: { courses: "Data Science" } }
)

В этой команде первый аргумент { name: "Alice Johnson" } — это фильтр, который находит документ для обновления. Второй аргумент { $push: { courses: "Data Science" } } указывает действие обновления. $push добавляет значение "Data Science" в массив courses.

Проверим изменение, снова найдя документ Alice.

db.students.find({ name: "Alice Johnson" }).pretty()

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

[
  {
    _id: ObjectId("..."),
    name: 'Alice Johnson',
    age: 22,
    courses: [ 'Mathematics', 'Computer Science', 'Physics', 'Data Science' ]
  }
]

Чтобы добавить несколько элементов одновременно, вы можете объединить $push с модификатором $each. Давайте добавим два новых занятия для Bob Smith.

db.students.updateOne(
    { name: "Bob Smith" },
    { $push: { activities: { $each: ["Robotics Club", "Swimming Team"] } } }
)

Здесь $each указывает $push добавить каждый элемент из предоставленного списка (["Robotics Club", "Swimming Team"]) в массив activities.

Проверьте это обновление также:

db.students.find({ name: "Bob Smith" }).pretty()

Вывод подтверждает, что оба новых занятия были добавлены.

[
  {
    _id: ObjectId("..."),
    name: 'Bob Smith',
    grades: [ 95, 87, 92 ],
    activities: [ 'Chess Club', 'Debate Team', 'Robotics Club', 'Swimming Team' ]
  }
]

Удаление элементов из массива

Помимо добавления элементов, необходимо уметь их и удалять. MongoDB предоставляет несколько операторов для этой цели. На этом этапе вы научитесь использовать оператор $pull для удаления элементов по значению и $pop для удаления по позиции.

Чтобы удалить определенный элемент из массива на основе его значения, используйте оператор $pull. Давайте удалим "Physics" из списка курсов Alice.

db.students.updateOne(
    { name: "Alice Johnson" },
    { $pull: { courses: "Physics" } }
)

Эта команда находит документ Alice и удаляет все вхождения "Physics" из ее массива courses. Проверьте результат:

db.students.find({ name: "Alice Johnson" }).pretty()

Вывод показывает, что "Physics" больше нет в массиве.

[
  {
    _id: ObjectId("..."),
    name: 'Alice Johnson',
    age: 22,
    courses: [ 'Mathematics', 'Computer Science', 'Data Science' ]
  }
]

Чтобы удалить несколько элементов, соответствующих значениям в списке, вы можете использовать оператор $pullAll. Давайте удалим "Chess Club" и "Debate Team" из занятий Bob.

db.students.updateOne(
    { name: "Bob Smith" },
    { $pullAll: { activities: ["Chess Club", "Debate Team"] } }
)

Проверьте обновление документа Bob:

db.students.find({ name: "Bob Smith" }).pretty()

Вывод подтверждает удаление указанных занятий.

[
  {
    _id: ObjectId("..."),
    name: 'Bob Smith',
    grades: [ 95, 87, 92 ],
    activities: [ 'Robotics Club', 'Swimming Team' ]
  }
]

Если вам нужно удалить элемент из начала или конца массива, вы можете использовать оператор $pop. Используйте 1 для удаления последнего элемента и -1 для удаления первого. Давайте удалим последний курс из списка Alice.

db.students.updateOne(
    { name: "Alice Johnson" },
    { $pop: { courses: 1 } }
)

Посмотрим на конечное состояние курсов Alice:

db.students.find({ name: "Alice Johnson" }).pretty()

Вывод показывает, что последний элемент, "Data Science", был удален.

[
  {
    _id: ObjectId("..."),
    name: 'Alice Johnson',
    age: 22,
    courses: [ 'Mathematics', 'Computer Science' ]
  }
]

Обновление элементов в массиве

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

Чтобы обновить один конкретный элемент в массиве, вы должны сначала найти документ и элемент, который вы хотите изменить. Затем вы можете использовать позиционный оператор $ для выполнения обновления. Давайте изменим "Mathematics" на "Advanced Mathematics" в массиве courses Alice.

db.students.updateOne(
    { name: "Alice Johnson", courses: "Mathematics" },
    { $set: { "courses.$": "Advanced Mathematics" } }
)

В этой команде фильтр { name: "Alice Johnson", courses: "Mathematics" } находит документ и определяет позицию первого вхождения "Mathematics" в массиве. Обновление { $set: { "courses.$": "Advanced Mathematics" } } использует courses.$ для ссылки на позицию соответствующего элемента и устанавливает его новое значение.

Проверьте изменение:

db.students.find({ name: "Alice Johnson" }).pretty()

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

[
  {
    _id: ObjectId("..."),
    name: 'Alice Johnson',
    age: 22,
    courses: [ 'Advanced Mathematics', 'Computer Science' ]
  }
]

Чтобы обновить все элементы в массиве, соответствующие условию, вы можете использовать оператор всех позиций $[ ]. Давайте увеличим все оценки Bob на 5 баллов, используя оператор $inc (инкремент).

db.students.updateOne(
    { name: "Bob Smith" },
    { $inc: { "grades.$[]": 5 } }
)

Здесь grades.$[] применяет операцию $inc к каждому элементу массива grades.

Проверьте новые оценки Bob:

db.students.find({ name: "Bob Smith" }).pretty()

Вывод показывает, что каждая оценка была увеличена на 5.

[
  {
    _id: ObjectId("..."),
    name: 'Bob Smith',
    grades: [ 100, 92, 97 ],
    activities: [ 'Robotics Club', 'Swimming Team' ]
  }
]

Запрос документов на основе содержимого массива

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

Чтобы найти все документы, в которых массив содержит определенный элемент, вы можете включить это значение в фильтр запроса. Давайте найдем всех студентов, записанных на "Computer Science".

db.students.find({ courses: "Computer Science" }).pretty()

Этот запрос вернет документ Alice, поскольку ее массив courses содержит "Computer Science".

Чтобы найти документы, в которых массив содержит все из указанного набора элементов, используйте оператор $all.

db.students.find({
    courses: { $all: ["Advanced Mathematics", "Computer Science"] }
}).pretty()

Это также вернет документ Alice, поскольку ее массив courses содержит оба этих значения.

Для более сложных условий для элементов массива оператор $elemMatch очень полезен. Он позволяет указать несколько критериев, которым должен соответствовать один элемент массива. Давайте найдем студентов, у которых есть хотя бы одна оценка выше 95.

db.students.find({
    grades: { $elemMatch: { $gt: 95 } }
}).pretty()

Этот запрос вернет документ Bob, поскольку у него есть оценки выше 95. $gt означает "больше чем" (greater than).

Вы также можете выполнять запросы на основе количества элементов в массиве, используя оператор $size. Давайте найдем студентов, которые участвуют ровно в двух мероприятиях.

db.students.find({
    activities: { $size: 2 }
}).pretty()

Это вернет документ Bob, поскольку его массив activities в настоящее время содержит два элемента.

Наконец, давайте добавим еще одного студента для практики комбинированного запроса.

db.students.insertOne({
    name: "Charlie Brown",
    courses: ["Art", "Music", "Literature"],
    grades: [88, 92, 85],
    activities: ["Painting Club"]
})

Теперь найдем студентов, которые изучают "Art" или "Music" (используя оператор $in) И имеют хотя бы одну оценку больше или равную 90 (используя $elemMatch с $gte).

db.students.find({
    courses: { $in: ["Art", "Music"] },
    grades: { $elemMatch: { $gte: 90 } }
}).pretty()

Этот запрос вернет документ "Charlie Brown", который соответствует обоим условиям.

Резюме

В этой лабораторной работе вы изучили основные методы работы с массивами в MongoDB. Вы начали с создания документов с полями-массивами, а затем практиковались в добавлении элементов с помощью $push и $each. Вы исследовали удаление элементов по значению с помощью $pull и $pullAll, а также по позиции с помощью $pop. Вы также узнали, как обновлять конкретные элементы массива с помощью позиционного оператора $ и все элементы с помощью оператора $[ ]. Наконец, вы практиковались в запросе документов на основе содержимого массива с использованием таких операторов, как $all, $elemMatch, $size и $in. Эти навыки имеют решающее значение для создания и управления приложениями со сложными, вложенными структурами данных в MongoDB.