1. 概要

Upsertは、挿入と更新の組み合わせです(inSERT + UPdate = upsert)。 upsert は、 update などのさまざまな更新方法で使用できます。 ] findAndModify 、およびreplaceOne

ここでMongoDB、では、upsertオプションはBoolean値です。 値がtrueであり、ドキュメントが指定されたクエリフィルターと一致するとします。 その場合、適用された更新操作によってドキュメントが更新されます。 値がtrueで、条件に一致するドキュメントがない場合、このオプションは新しいドキュメントをコレクションに挿入します。 新しいドキュメントには、フィルターと適用された操作に基づくフィールドが含まれます。

このチュートリアルでは、最初にMongoDBシェルクエリの upsert を確認してから、Javaドライバーコードを使用します。

2. データベースの初期化

upsert 操作を実行する前に、まず新しいデータベースbaeldungとサンプルコレクションvehicleをセットアップする必要があります。

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. updateメソッドを使用する

このセクションでは、upsertオプションをupdateメソッドで使用する方法を学習します。 upsertオプションの主な目的は、適用されたフィルターに基づいて既存のドキュメントを更新するか、フィルターが一致しない場合は新しいドキュメントを挿入することです

例として、 $setOnInsert演算子をupsertオプションとともに使用して、ドキュメントに新しいフィールドを挿入する際の追加の利点を取得します。

フィルタ条件がコレクションの既存のドキュメントと一致するクエリを確認してみましょう。

db.vehicle.update(
{
    "modelName":"X5"
},
{
    "$set":{
        "companyName":"Hero Honda"
    }
},
{
    "upsert":true
});

上記のクエリは、次のドキュメントを返します。

{ 
    "nMatched" : 1, 
    "nUpserted" : 0,
    "nModified" : 1 
}

ここに、上記のmongoシェルクエリに対応するJavaドライバーコードが表示されます。

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”に更新されます。

それでは、$ setOnInsert演算子を使用したupsertオプションの例を確認してみましょう。 これは、新しいドキュメントを追加する場合にのみ適用されます。

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")
}

$setOnInsertオプションを使用した上記の更新クエリのJavaドライバーコードは次のようになります。

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メソッドの使用

findAndModifyメソッドを使用してupsertオプションを使用することもできます。 この方法の場合、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);

ここでは、最初にフィルター条件を作成し、それに基づいて、既存のドキュメントを更新するか、コレクションVehicleに新しいドキュメントを追加します。

5. replaceOneメソッドの使用

replaceOneメソッドを使用してupsert操作を実行してみましょう。 MongoDBのreplaceOneメソッドは、条件が一致した場合にコレクション内の単一のドキュメントを置き換えるだけです。

まず、replaceメソッドのMongoシェルクエリを調べてみましょう。

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. 結論

この記事では、MongoDBのさまざまな更新方法でupsert操作を実行する方法を見てきました。 最初に、updateおよびfindAndModifyメソッドを使用してupsertを実行し、次にreplaceOneメソッドを使用する方法を学びました。 つまり、MongoシェルクエリとJavaドライバーコードを使用してアップサート操作を実装しました。

すべてのケースの実装は、GitHubにあります。