Как и другие системы управления базами данных MongoDB предоставляет возможность обновления данных. Для этого доступно ряд функций.
Если нам надо полностью заменить один документ другим, также может использоваться функция replaceOne:
db.collection.replaceOne(filter, update, options)
filter
: принимает запрос на выборку документа, который надо обновить
update
: представляет новый документ, который заместит старый при обновлении
options
: определяет дополнительные параметры при обновлении документов, основным из которых является параметр upsert
.
Если параметр upsert
имеет значение true
, что mongodb будет обновлять документ, если он найден, и создавать новый,
если такого документа нет. Если же он имеет значение false
, то mongodb не будет создавать новый документ, если запрос на выборку не найдет ни одного документа.
Например:
db.users.replaceOne({name: "Bob"}, {name: "Bob", age: 25})
В данном случае находим документ, в котором name ="Bob", и заменяем его документом {name: "Bob", age: 25}
После выполнения операции консоль вернет на результат обновления:
test> db.users.replaceOne({name: "Bob"}, {name: "Bob", age: 25}) { acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 }
В полученном результате параметр matchedCount
указывает на количество документов, которые соответствуют запросу. А параметр modifiedCount
указывает на
количество измененных документов. То есть в данном случае соответствует запросу 1 документ и он же был изменен.
Часто не требуется обновлять весь документ, а только значение одного или нескольких его свойств. Для этого применяются функции updateOne() (обновляет только один документ) и updateMany() (обновляет множество документов).
Для обновления отдельных полей в этих функциях применяется оператор $set. Если документ не содержит обновляемое поле, то оно создается.
db.users.updateOne({name : "Tom", age: 22}, {$set: {age : 28}})
Здесь мы ищем документ с name="Tom" и age=22 и устанавливаем для его свойства age значение 28
Если необходимо обновить все документы, соответствующие некоторому критерию, то применяется функция updateMany():
db.users.updateMany({name : "Tom"}, {$set: {name : "Tomas"}})
Если обновляемого поля в документе нет, то оно добавляется:
db.users.updateOne({name : "Tom", age: 28}, {$set: {salary : 300}})
Если надо обновить значения нескольких полей, то они передаются оператору $set
через запятую:
db.users.updateOne({name : "Tom"}, {$set: {name: "Tomas", age : 25}})
Для простого увеличения значения числового поля на определенное количество единиц применяется оператор $inc. Если документ не содержит обновляемое поле, то оно создается. Данный оператор применим только к числовым значениям.
db.users.updateOne({name : "Tom"}, {$inc: {age:2}})
Для удаления отдельного ключа используется оператор $unset:
db.users.updateOne({name : "Tom"}, {$unset: {salary: 1}})
Если вдруг подобного ключа в документе не существует, то оператор не оказывает никакого влияния. Также можно удалять сразу несколько полей:
db.users.updateOne({name : "Tom"}, {$unset: {salary: 1, age: 1}})
Оператор $push позволяет добавить еще одно значение к уже существующему. Например, если ключ в качестве значения хранит массив:
db.users.updateOne({name : "Tom"}, {$push: {languages: "russian"}})
Выше использовалась функция updateOne
, но этот оператор также применяется и в функции updateMany
db.users.updateMany({name : "Tom"}, {$push: {languages: "russian"}})
Если ключ, для которого мы хотим добавить значение, не представляет массив, то мы получим ошибку Cannot apply $push/$pushAll modifier to non-array
.
Используя оператор $each
, можно добавить сразу несколько значений:
db.users.updateOne({name : "Tom"}, {$push: {languages: {$each: ["russian", "spanish", "italian"]}}})
Еще пара операторов позволяет настроить вставку. Оператор $position задает позицию в массиве для вставки элементов, а оператор $slice указывает, сколько элементов оставить в массиве после вставки.
db.users.updateOne({name : "Tom"}, {$push: {languages: {$each: ["german", "spanish", "italian"], $position:1, $slice:5}}})
В данном случае элементы ["german", "spanish", "italian"]
будут вставляться в массив languages с 1-го индекса, и после вставки, в массиве останутся
только 5 первых элементов.
Оператор $addToSet подобно оператору $push добавляет объекты в массив. Отличие состоит в том, что $addToSet добавляет данные, если их еще нет в массиве (
при добавлении через $push
данные дублируются, если добавляются элементы, которые уже есть в массиве):
db.users.updateOne({name : "Tom"}, {$addToSet: {languages: "russian"}})
Оператор $pop
позволяет удалять элемент из массива:
db.users.updateOne({name : "Tom"}, {$pop: {languages: 1}})
Указывая для ключа languages значение 1, мы удаляем первый элемент с конца. Чтобы удалить первый элемент сначала массива, надо передать отрицательное значение:
db.users.updateOne({name : "Tom"}, {$pop: {languages: -1}})
Несколько иное действие предполагает оператор $pull
. Он удаляет каждое вхождение элемента в массив. Например, через оператор $push
мы можем добавить одно и то же значение в массив несколько раз. И теперь с помощью $pull удалим его:
db.users.updateOne({name : "Tom"}, {$pull: {languages: "english"}})
А если мы хотим удалить не одно значение, а сразу несколько, тогда мы можем применить оператор $pullAll
:
db.users.updateOne({name : "Tom"}, {$pullAll: {languages: ["english", "german", "french"]}})