1. 概要

MongoDB は、C ++で記述された、クロスプラットフォームのドキュメント指向のオープンソースNoSQLデータベースです。 さらに、MongoDBは、高性能、高可用性、および自動スケーリングを提供します。

MongoDBのドキュメントを更新するために、 updateOne findOneAndUpdate、などのさまざまなメソッドを使用できます。 さらに、MongoDBは、更新メソッドにさまざまな演算子を提供します。

このチュートリアルでは、MongoDBで更新操作を実行するためのさまざまなアプローチについて説明します。 それぞれのアプローチについて、最初にmongoシェルクエリについて説明し、次にJavaでの実装について説明します。

2. データベースの設定

更新クエリに進む前に、まずデータベース baeldung と、サンプルコレクション student:を作成しましょう。

use baeldung;
db.createCollection(student);

例として、 insertMany クエリを使用して、コレクションstudentにいくつかのドキュメントを追加しましょう。

db.student.insertMany([
    {
        "student_id": 8764,
        "student_name": "Paul Starc",
        "address": "Hostel 1",
        "age": 16,
        "roll_no":199406
    },
    {
        "student_id": 8765,
        "student_name": "Andrew Boult",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199408
    }
]);

挿入が成功すると、acknowledged:trueのJSONが取得されます。

{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("621b078485e943405d04b557"),
	ObjectId("621b078485e943405d04b558")
    ]
}

それでは、MongoDBのドキュメントを更新するさまざまな方法について詳しく見ていきましょう。

3. updateOneメソッドの使用

MongoDBでの更新操作は、新しいフィールドを追加するか、フィールドを削除するか、既存のフィールドを更新することで実行できます。 updateOne メソッドは、適用されたクエリフィルターに基づいてコレクション内の単一のドキュメントを更新します。 最初にフィルターに一致するドキュメントを検索し、次に指定されたフィールドを更新します。

さらに、 updateメソッドでは、$ set、$ unset、$incなどのさまざまな演算子を使用できます。

実例を示すために、コレクションの単一のドキュメントを更新するクエリを調べてみましょう。

db.student.updateOne(
    { 
        "student_name" : "Paul Starc"
    },
    { 
        $set: {
            "address" : "Hostel 2"
        }
    }
 );

以下に示すような出力が得られます。

{
    "acknowledged":true,
    "matchedCount":1,
    "modifiedCount":1
}

上記のupdateOneクエリのJavaドライバーコードを確認してみましょう。

UpdateResult updateResult = collection.updateOne(Filters.eq("student_name", "Paul Starc"),
Updates.set("address", "Hostel 2"));

ここでは、最初にstudent_nameフィールドを使用してドキュメントをフィルタリングしました。 次に、ドキュメントのアドレスをstudent_name「PaulStarc」で更新します。

4. updateManyメソッドの使用

updateMany メソッドは、指定されたフィルターに一致するMongoDBコレクション内のすべてのドキュメントを更新します。  updateManyを使用する利点の1つは、古いドキュメントのフィールドを失うことなく、複数のドキュメントを更新できることです。

updateManyメソッドを使用したMongoDBシェルクエリを見てみましょう。

db.student.updateMany(
    { 
        age: { 
            $lt: 20
         } 
    },
    { 
        $set:{ 
            "Review" : true 
        }
    }
);

上記のコマンドは、次の出力を返します。

{
    "acknowledged":true,
    "matchedCount":2,
    "modifiedCount":2
}

ここで、 matchedCount には一致したドキュメントの数が含まれ、ModifiedCountには変更されたドキュメントの数が含まれます。

次に、updateManyメソッドを使用してJavaドライバーコードを調べてみましょう。

UpdateResult updateResult = collection.updateMany(Filters.lt("age", 20), Updates.set("Review", true));

ここでは、 age が20未満のすべてのドキュメントがフィルタリングされ、Reviewフィールドがtrueに設定されます。

5. replaceOneメソッドの使用

MongoDBのreplaceOneメソッドは、ドキュメント全体を置き換えます。  replaceOneの欠点の1つは、すべての古いフィールドが新しいフィールドに置き換えられ、古いフィールドも失われることです。

db.student.replaceOne(
    { 
        "student_id": 8764
    },
    {
        "student_id": 8764,
        "student_name": "Paul Starc",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199406
    }
);

この場合、次の出力が得られます。

{
    "acknowledged":true,
    "matchedCount":1,
    "modifiedCount":1
}

一致するものが見つからない場合、操作はmatchedCountを0として返します。

{
    "acknowledged":true,
    "matchedCount":0,
    "modifiedCount":0
}

replaceOne メソッドを使用して、対応するJavaドライバーコードを記述してみましょう。

Document replaceDocument = new Document();
replaceDocument
  .append("student_id", 8764)
  .append("student_name", "Paul Starc")
  .append("address", "Hostel 2")
  .append("age",18)
  .append("roll_no", 199406);
UpdateResult updateResult = collection.replaceOne(Filters.eq("student_id", 8764), replaceDocument);

上記のコードでは、古いドキュメントを置き換えるドキュメントを作成しました。  student_id 8764のドキュメントは、新しく作成されたドキュメントに置き換えられます。

6. findOneAndReplaceメソッドの使用

findOneAndReplace メソッドは、MongoDBが提供する高度な更新メソッドの1つであり、指定された選択基準に基づいて最初に一致したドキュメントを置き換えます。 デフォルトでは、このメソッドは元のドキュメントを返します。 findOneAndReplace のさまざまなオプションを使用して、必要に応じてドキュメントを並べ替えて投影できます。

つまり、 findOneAndReplace は、適用されたフィルターに基づいて、コレクションの最初に一致するドキュメントを置き換えます。

db.student.findOneAndReplace(
    { 
        "student_id" : { 
            $eq : 8764 
        }
    },
    { 
        "student_id" : 8764,
        "student_name" : "Paul Starc",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199406 
    },
    {
        returnNewDocument: false
    }
);

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

{
    "student_id":8764,
    "student_name":"Paul Starc",
    "address":"Hostel 1",
    "age":16,
    "roll_no":199406
}

returnNewDocumenttrueに設定すると、操作は代わりに置き換えられたドキュメントを返します。

{
    "student_id":8764,
    "student_name":"Paul Starc",
    "address":"Hostel 2",
    "age":18,
    "roll_no":199406
}

次に、 findOneAndReplace メソッドを使用して、返されたドキュメントのstudent_idフィールドとageフィールドを投影します。

db.student.findOneAndReplace(
    { 
        "student_id" : {
        $eq : 8764 
        } 
    },
    { 
        "student_id" : 8764, 
        "student_name" : "Paul Starc",
        "address": "Hostel 2",
        "age": 18,
        "roll_no":199406 
    },
    { 
        projection: { 
            "_id" : 0,
            "student_id":1,
            "age" : 1 
        } 
    }
);

上記のクエリの出力には、投影されたフィールドのみが含まれます。

{
    "student_id":"8764",
    "age":16
}

findOneAndReplace:のさまざまなオプションを使用した上記のクエリのJavaドライバーコード

Document replaceDocument = new Document();
replaceDocument
  .append("student_id", 8764)
  .append("student_name", "Paul Starc")
  .append("address", "Hostel 2")
  .append("age", 18)
  .append("roll_no", 199406);
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndReplace(
  Filters.eq("student_id", 8764), 
  replaceDocument,
  new FindOneAndReplaceOptions().upsert(true).sort(sort).projection(projection).returnDocument(ReturnDocument.AFTER));

上記のクエリでは、 findOneAndReplace メソッドは、最初に roll_no、に基づいてドキュメントを昇順で並べ替え、新しく作成されたドキュメントはドキュメントを student_id “8764に置き換えます。 」。

7. findOneAndUpdateメソッドの使用

findOneAndUpdate メソッドは、コレクション内で最初に一致したドキュメントを更新します。 複数のドキュメントが選択基準に一致する場合、最初に一致したドキュメントのみが更新されます。 ドキュメントを更新しても、_idフィールドの値は変更されません。

db.student.findOneAndUpdate(
    { 
        "student_id" : 8764
    },
    { 
        $inc : { 
            "roll_no" : 5
        } 
    },
    { 
        sort: { 
            "roll_no" : 1 
        }, 
        projection: { 
            "_id" : 0,
            "student_id":1,
            "address" : 1
        }
    }
);

クエリの出力には、古いドキュメントのstudentIdaddressのみが含まれます。

{
    "student_id":8764,
    "address":"Hostel 1"
}

findOneAndUpdate のさまざまなオプションを使用した上記のクエリのJavaドライバーコードは次のとおりです

Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndUpdate(
  Filters.eq("student_id", 8764),
  Updates.inc("roll_no", 5), 
  new FindOneAndUpdateOptions().sort(sort).projection(projection).returnDocument(ReturnDocument.BEFORE));

この場合、 findOneAndUpdate メソッドは、最初にroll_noに基づいてドキュメントを昇順で並べ替えます。 上記のクエリは、 roll_no を5ずつインクリメントしてから、student_idおよびaddressフィールドを返します。

8. 結論

この記事では、MongoDBのドキュメントを更新するさまざまな方法を見てきました。 まず、MongoDBシェルクエリを調べてから、対応するJavaドライバーコードについて説明しました。

これらすべての例とコードスニペットの実装は、GitHubにあります。