Введение
В этой лабораторной работе вы научитесь манипулировать массивами в документах MongoDB. Вы попрактикуетесь в добавлении, удалении и обновлении элементов массива с использованием мощных операторов обновления MongoDB. Лабораторная работа содержит пошаговые инструкции и практические примеры, которые помогут вам освоить управление массивами в ваших базах данных MongoDB.
Вы начнете с добавления элементов в массив с помощью оператора $push. Далее вы научитесь удалять элементы с помощью операторов $pull и $pullAll. Вы также узнаете, как изменять конкретные элементы в массиве и как использовать $addToSet для обеспечения того, чтобы массив содержал только уникальные элементы. Наконец, вы научитесь удалять существующие дубликаты из массива с помощью конвейера агрегации (aggregation pipeline).
Добавление элементов в массив с помощью $push
На этом шаге вы научитесь добавлять новые элементы в массив в документе MongoDB с помощью оператора $push. Этот оператор добавляет указанное значение в конец массива.
Сначала откройте оболочку MongoDB (MongoDB shell) для взаимодействия с вашей базой данных. Все операции с базой данных в этой лабораторной работе будут выполняться внутри этой оболочки.
mongosh
Оказавшись в оболочке, переключитесь на базу данных arraylab. Эта база данных была создана для вас в процессе настройки.
use arraylab
Скрипт настройки также создал коллекцию students с одним документом. Найдем этот документ, чтобы увидеть его текущее состояние.
db.students.findOne({ name: "Alice Johnson" })
Вы должны увидеть следующий вывод, который показывает, что Алиса записана на два курса:
{
_id: ObjectId('...'),
name: 'Alice Johnson',
courses: [ 'Mathematics', 'Computer Science' ]
}
Теперь давайте добавим новый курс, "Data Structures", в массив courses Алисы, используя оператор $push.
db.students.updateOne(
{ name: "Alice Johnson" },
{ $push: { courses: "Data Structures" } }
)
Метод updateOne находит документ, соответствующий фильтру { name: "Alice Johnson" }, и применяет обновление { $push: { courses: "Data Structures" } }. Оператор $push добавляет новый курс в массив courses.
Вы также можете добавлять несколько элементов одновременно, комбинируя $push с модификатором $each. Давайте добавим "Physics" и "Chemistry" в массив.
db.students.updateOne(
{ name: "Alice Johnson" },
{ $push: { courses: { $each: ["Physics", "Chemistry"] } } }
)
Чтобы убедиться, что все новые курсы были добавлены, снова выполните команду findOne.
db.students.findOne({ name: "Alice Johnson" })
Обновленный документ теперь содержит все пять курсов:
{
_id: ObjectId('...'),
name: 'Alice Johnson',
courses: [
'Mathematics',
'Computer Science',
'Data Structures',
'Physics',
'Chemistry'
]
}
Удаление элементов из массива
На этом шаге вы научитесь удалять элементы из массива с помощью операторов $pull и $pullAll. $pull удаляет все вхождения указанного значения, в то время как $pullAll удаляет все вхождения нескольких указанных значений.
Вы должны все еще находиться в оболочке mongosh из предыдущего шага. Давайте начнем с удаления курса "Physics" из списка Алисы с помощью оператора $pull.
db.students.updateOne(
{ name: "Alice Johnson" },
{ $pull: { courses: "Physics" } }
)
Эта команда находит документ для "Alice Johnson" и удаляет строку "Physics" из ее массива courses.
Далее, давайте удалим несколько курсов одновременно. Оператор $pullAll идеально подходит для этого. Мы удалим "Mathematics" и "Chemistry".
db.students.updateOne(
{ name: "Alice Johnson" },
{ $pullAll: { courses: ["Mathematics", "Chemistry"] } }
)
Теперь давайте проверим конечное состояние документа, чтобы увидеть, какие курсы остались.
db.students.findOne({ name: "Alice Johnson" })
Вывод показывает, что "Physics", "Mathematics" и "Chemistry" были удалены, осталось только два курса.
{
_id: ObjectId('...'),
name: 'Alice Johnson',
courses: [ 'Computer Science', 'Data Structures' ]
}
Обновление конкретных элементов в массиве
На этом шаге вы научитесь изменять конкретные элементы внутри массива. Это полезно, когда ваш массив содержит объекты, и вам нужно обновить поле в одном из этих объектов.
Сначала вставим новый документ студента. Массив courses этого документа будет содержать объекты, каждый из которых имеет поля name и grade.
db.students.insertOne({
name: "Bob Smith",
courses: [
{ name: "Mathematics", grade: "B" },
{ name: "Computer Science", grade: "A" },
{ name: "Physics", grade: "C" }
]
})
Предположим, мы хотим изменить оценку Боба по "Computer Science" с "A" на "A+". Мы можем использовать позиционный оператор $. Этот оператор действует как заполнитель для первого элемента, соответствующего условию запроса.
db.students.updateOne(
{ name: "Bob Smith", "courses.name": "Computer Science" },
{ $set: { "courses.$.grade": "A+" } }
)
В этой команде запрос { "courses.name": "Computer Science" } идентифицирует правильный элемент массива. Затем обновление { $set: { "courses.$.grade": "A+" } } использует $ для ссылки на этот элемент и обновления его поля grade.
Проверим изменение.
db.students.findOne({ name: "Bob Smith" })
Вывод покажет обновленную оценку:
{
_id: ObjectId('...'),
name: 'Bob Smith',
courses: [
{ name: 'Mathematics', grade: 'B' },
{ name: 'Computer Science', grade: 'A+' },
{ name: 'Physics', grade: 'C' }
]
}
Вы также можете обновить все элементы массива одновременно, используя оператор позиционирования для всех элементов $[ ]. Давайте добавим поле semester ко всем курсам Боба.
db.students.updateOne(
{ name: "Bob Smith" },
{ $set: { "courses.$[].semester": "Fall 2023" } }
)
Проверьте конечный документ, чтобы увидеть результат.
db.students.findOne({ name: "Bob Smith" })
Все объекты курсов в массиве теперь имеют поле semester.
{
_id: ObjectId('...'),
name: 'Bob Smith',
courses: [
{ name: 'Mathematics', grade: 'B', semester: 'Fall 2023' },
{ name: 'Computer Science', grade: 'A+', semester: 'Fall 2023' },
{ name: 'Physics', grade: 'C', semester: 'Fall 2023' }
]
}
Обеспечение уникальности элементов с помощью $addToSet
На этом шаге вы научитесь использовать оператор $addToSet. Этот оператор добавляет элемент в массив только в том случае, если он еще не существует в массиве, тем самым предотвращая дублирование записей.
Сначала добавим нового студента с массивом навыков.
db.students.insertOne({
name: "Emma Wilson",
skills: ["Python", "JavaScript"]
})
Теперь попробуем добавить "Python" снова, используя $addToSet. Поскольку "Python" уже есть в массиве, эта операция не изменит документ.
db.students.updateOne(
{ name: "Emma Wilson" },
{ $addToSet: { skills: "Python" } }
)
Проверим документ, чтобы убедиться.
db.students.findOne({ name: "Emma Wilson" })
Вы увидите, что массив skills не изменился, потому что "Python" уже присутствовал.
{
_id: ObjectId('...'),
name: 'Emma Wilson',
skills: [ 'Python', 'JavaScript' ]
}
Как и $push, $addToSet может быть объединен с модификатором $each для добавления нескольких значений. Будут добавлены только те значения, которых еще нет в массиве.
db.students.updateOne(
{ name: "Emma Wilson" },
{ $addToSet: {
skills: {
$each: ["React", "Node.js", "Python", "TypeScript"]
}
} }
)
Проверим конечный документ.
db.students.findOne({ name: "Emma Wilson" })
Новые, уникальные навыки были добавлены, в то время как дубликат "Python" был проигнорирован.
{
_id: ObjectId('...'),
name: 'Emma Wilson',
skills: [ 'Python', 'JavaScript', 'React', 'Node.js', 'TypeScript' ]
}
Удаление существующих дубликатов из массива
В то время как $addToSet предотвращает добавление новых дубликатов, иногда у вас может быть документ, в котором массив уже содержит повторяющиеся значения. На этом шаге вы узнаете, как удалить существующие дубликаты с помощью конвейера агрегации.
Сначала вставим документ с массивом skills, содержащим дубликаты.
db.students.insertOne({
name: "Michael Chen",
skills: ["Python", "JavaScript", "Python", "React", "JavaScript", "Node.js"]
})
Чтобы удалить эти дубликаты, мы можем использовать конвейер агрегации с этапом $merge. Этот конвейер прочитает документ, создаст новый массив с уникальными элементами, а затем обновит исходный документ.
Сначала нам нужно создать индекс по полю name, чтобы операция $merge работала корректно:
db.students.createIndex({ name: 1 }, { unique: true })
Теперь выполните следующую команду агрегации:
db.students.aggregate([
{ $match: { name: "Michael Chen" } },
{ $project: {
name: 1,
skills: { $setUnion: "$skills" }
} },
{ $merge: { into: "students", on: "name", whenMatched: "replace" } }
])
Разберем этот конвейер:
$match: Этот этап фильтрует документы, обрабатывая только документ для "Michael Chen".$project: Этот этап изменяет структуру документа. Мы сохраняем полеnameи заменяем массивskillsрезультатом$setUnion: "$skills". Оператор$setUnionпринимает массив и возвращает новый массив, содержащий только уникальные элементы.$merge: Этот этап записывает результаты конвейера обратно в коллекциюstudents. Он находит документ для обновления на основе поляname(on: "name") и заменяет весь документ новым из конвейера (whenMatched: "replace"). Созданный нами индекс обеспечивает эффективное сопоставление и обновление.
Теперь проверим, были ли удалены дубликаты.
db.students.findOne({ name: "Michael Chen" })
В выводе будет показан массив skills только с уникальными элементами. Порядок элементов может отличаться.
{
_id: ObjectId('...'),
name: 'Michael Chen',
skills: [ 'JavaScript', 'Node.js', 'Python', 'React' ]
}
Резюме
В этой лабораторной работе вы изучили несколько основных методов управления массивами в MongoDB. Вы практиковались в добавлении элементов с помощью $push, их удалении с помощью $pull и $pullAll, а также в обновлении конкретных элементов с использованием позиционного оператора $. Вы также узнали, как поддерживать уникальные элементы в массиве с помощью $addToSet и как удалять существующие дубликаты с помощью конвейера агрегации с $setUnion и $merge. Эти навыки являются основополагающими для создания динамичных и надежных приложений с использованием MongoDB.

