1. Обзор
Upsert — это комбинация вставки и обновления (inSERT + UPdate = upsert). Мы можем использовать upsert
с различными методами обновления, т . е. update
, findAndModify
и replaceOne
.
Здесь, в MongoDB , опция upsert
является логическим
значением. Предположим, что значение равно true
и документы соответствуют указанному фильтру запроса. В этом случае примененная операция обновления обновит документы. Если значение равно true
и ни один документ не соответствует условию, этот параметр вставляет в коллекцию новый документ. Новый документ будет содержать поля на основе фильтров и примененных операций.
В этом руководстве мы сначала рассмотрим upsert
в запросе MongoDB Shell, а затем воспользуемся кодом драйвера Java.
2. Инициализация базы данных
Прежде чем мы перейдем к выполнению операций upsert
, сначала нам нужно настроить новую базу данных foreach
и образец коллекции, транспортное средство
:
db.vehicle.insertMany([
{
"companyName":"Nissan",
"modelName":"GTR",
"launchYear":2016,
"type":"Sports",
"registeredNo":"EPS 5561"
},
{
"companyName":"BMW",
"modelName":"X5",
"launchYear":2020,
"type":"SUV",
"registeredNo":"LLS 6899"
},
{
"companyName":"Honda",
"modelName":"Gold Wing",
"launchYear":2018,
"type":"Bike",
"registeredNo":"LKS 2477"
}]);
В случае успешной вставки приведенная выше команда напечатает JSON, подобный показанному ниже:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("623c1db39d55d4e137e4781b"),
ObjectId("623c1db39d55d4e137e4781c"),
ObjectId("623c1db39d55d4e137e4781d")
]
}
Мы успешно добавили фиктивные данные в транспортное средство
для сбора .
3. Использование метода обновления
В этом разделе мы научимся использовать опцию upsert
с методом обновления .
Основная цель параметра upsert
— обновить существующий документ на основе примененного фильтра или вставить новый документ, если фильтр не соответствует требованиям .
В качестве иллюстрации мы будем использовать оператор $setOnInsert
с опцией upsert
, чтобы получить дополнительное преимущество при вставке новых полей в документ.
Давайте проверим запрос, в котором условие фильтра соответствует существующему документу коллекции:
db.vehicle.update(
{
"modelName":"X5"
},
{
"$set":{
"companyName":"Hero Honda"
}
},
{
"upsert":true
});
Приведенный выше запрос вернет следующий документ:
{
"nMatched" : 1,
"nUpserted" : 0,
"nModified" : 1
}
Здесь мы увидим код драйвера Java, соответствующий приведенному выше запросу оболочки mongo:
UpdateOptions options = new UpdateOptions().upsert(true);
UpdateResult updateResult = collection.updateOne(Filters.eq("modelName", "X5"),
Updates.combine(Updates.set("companyName", "Hero Honda")), options);
System.out.println("updateResult:- " + updateResult);
В приведенном выше запросе поле modelName
«X5» уже существует в коллекции, поэтому поле companyName
этого документа будет обновлено до «Hero Honda».
Теперь давайте рассмотрим пример опции upsert с использованием оператора $
setOnInsert
. Он будет применим только в случае добавления нового документа:
db.vehicle.update(
{
"modelName":"GTPR"
},
{
"$set":{
"companyName":"Hero Honda"
},
"$setOnInsert":{
"launchYear" : 2022,
"type" : "Bike",
"registeredNo" : "EPS 5562"
},
},
{
"upsert":true
});
Приведенный выше запрос вернет следующий документ:
{
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("623b378ed648af670fe50e7f")
}
Код драйвера Java приведенного выше запроса на обновление с параметром $setOnInsert
будет таким:
UpdateResult updateSetOnInsertResult = collection.updateOne(Filters.eq("modelName", "GTPR"),
Updates.combine(Updates.set("companyName", "Hero Honda"),
Updates.setOnInsert("launchYear", 2022),
Updates.setOnInsert("type", "Bike"),
Updates.setOnInsert("registeredNo", "EPS 5562")), options);
System.out.println("updateSetOnInsertResult:- " + updateSetOnInsertResult);
Здесь, в приведенном выше запросе, условие фильтра поля modelName
«GTPR» не соответствует ни одному документу коллекции, поэтому мы добавим в коллекцию новый документ. Важно отметить, что $setOnInsert
добавляет все поля в новый документ.
4. Использование метода findAndModify
Мы также можем использовать опцию upsert , используя метод
findAndModify
. Для этого метода значение параметра upsert
по умолчанию равно false
. Если мы установим для параметра upsert
значение true
, он будет работать точно так же, как и метод обновления.
Давайте рассмотрим вариант использования метода findAndModify
с опцией upsert
true
:
db.vehicle.findAndModify(
{
query:{
"modelName":"X7"
},
update: {
"$set":{
"companyName":"Hero Honda"
}
},
"upsert":true,
"new":true
});
В этом случае приведенный выше запрос вернет только что созданный документ. Давайте проверим код драйвера Java для приведенного выше запроса:
FindOneAndUpdateOptions upsertOptions = new FindOneAndUpdateOptions();
upsertOptions.returnDocument(ReturnDocument.AFTER);
upsertOptions.upsert(true);
Document resultDocument = collection.findOneAndUpdate(Filters.eq("modelName", "X7"),
Updates.set("companyName", "Hero Honda"), upsertOptions);
System.out.println("resultDocument:- " + resultDocument);
Здесь мы сначала создали условие фильтра и на его основе либо обновим существующий документ, либо добавим новый документ в средство
сбора .
5. Использование метода replaceOne
Давайте выполним операцию upsert
, используя метод replaceOne
. Метод replaceOne
MongoDB просто заменяет один документ в коллекции, если условие соответствует.
Во-первых, давайте рассмотрим запрос оболочки Mongo для метода replace:
db.vehicle.replaceOne(
{
"modelName":"GTPR"
},
{
"modelName" : "GTPR",
"companyName" : "Hero Honda",
"launchYear" : 2022,
"type" : "Bike",
"registeredNo" : "EPS 5562"
},
{
"upsert":true
});
Приведенный выше запрос вернет следующий ответ:
{
"acknowledged" : true,
"matchedCount" : 1,
"modifiedCount" : 1
}
Теперь давайте напишем приведенный выше запрос, используя код драйвера Java:
Document replaceDocument = new Document();
replaceDocument.append("modelName", "GTPP")
.append("companyName", "Hero Honda")
.append("launchYear", 2022)
.append("type", "Bike")
.append("registeredNo", "EPS 5562");
UpdateResult updateReplaceResult = collection.replaceOne(Filters.eq("modelName", "GTPP"), replaceDocument, options);
System.out.println("updateReplaceResult:- " + updateReplaceResult);
Здесь, в этом случае, нам нужно сначала создать новый документ, которым мы хотим заменить существующий документ, а с опцией upsert
true
мы заменим документ, только если условие будет выполнено.
6. Заключение
В этой статье мы увидели, как выполнить операцию upsert
с различными методами обновления MongoDB. Во-первых, мы научились выполнять upsert
с помощью метода update
и findAndModify
, а затем использовать метод replaceOne
. Короче говоря, мы реализовали операцию upsert, используя запрос оболочки Mongo и код драйвера Java.
Реализацию всех кейсов можно найти на GitHub .