集計パイプラインの更新
項目一覧
更新操作を行うには、集計パイプラインを使用できます。 集計パイプラインをビルドして実行すると、 MongoDB Atlas 、 MongoDB Compass 、 MongoDB Shell 、またはドライバー で更新操作を行えるようになります。
更新操作により、集約パイプラインは以下のステージで構成されます。
集計パイプラインを使用すると、現在のフィールド値に基づいて条件付きのアップデートを表現したり、あるフィールドを他のフィールドの値を使用してアップデートするなど、より表現内容の多いアップデート ステートメントが可能になります。
Atlasで更新集計パイプラインを作成
MongoDB Atlas UI を使用して、アップデートを実行するための集計パイプラインを構築できます。 MongoDB Atlas UI で集計パイプラインを作成および実行するユーザーには、 Project Data Access Read Only
ロール以上のロールが必要です。
アップデートを実行するための集計パイプラインを作成
集計ステージを選択します。
左下のパネルにあるSelectドロップダウン メニューから集計ステージを選択します。
ドロップダウン メニューの右側にあるトグルで、ステージが有効かどうかを指定します。
集計を使用して更新を実行するには、次のいずれかのステージを使用します。
集計ステージを入力してください。
ステージに適切な値を入力します。 コメントモードが有効になっている場合、パイプラインビルダは選択したステージの構文ガイドラインを提供します。
ステージを変更すると、Atlasは現在のステージの結果に基づいて右側のプレビュー ドキュメントが更新されます。
集計ステージに含めることができる内容の例については、このページの例を参照してください。
必要に応じてステージを追加します。 Atlas で集計パイプラインを作成する方法の詳細については、「 集計パイプラインの作成 」を参照してください。
集計パイプラインをエクスポート
[言語にエクスポート] をクリックします。
このボタンは、パイプラインビルダの上部にあります。
希望のエクスポート言語を選択します。
Export Pipeline Toメニューで、目的の言語を選択します。
左側のMy Pipelineペインには、MongoDB Shell 構文でパイプラインが表示されます。これを直接コピーして、MongoDB Shell でパイプラインを実行することができます。
右側のペインには、選択した言語でパイプラインが表示されます。ご希望の言語を選択します。
必要に応じて、オプションを選択します。
(任意):選択した言語に必要なインポート ステートメントを含めるには、Include Import Statements オプションをオンにします。
(オプション):Include Driver Syntax オプションにチェックを入れると、次のようなドライバー固有のコードが含まれます。
クライアントを初期化
データベースとコレクションの指定
集計操作の実行
パイプラインのコピー
パイプラインの右上にある Copy ボタンをクリックして、選択した言語のパイプラインをクリップボードにコピーします。コピーしたパイプラインをアプリケーションに貼り付けます。
例
次の例は、集計パイプライン ステージ $set
、$replaceRoot
、および$addFields
を使用して更新を実行する方法を示しています。
updateOne と $set
students
コレクションの例えを作成します(コレクションが現在存在しない場合は、挿入操作でコレクションが作成されます)。
db.students.insertMany( [ { _id: 1, test1: 95, test2: 92, test3: 90, modified: new Date("01/05/2020") }, { _id: 2, test1: 98, test2: 100, test3: 102, modified: new Date("01/05/2020") }, { _id: 3, test1: 95, test2: 110, modified: new Date("01/04/2020") } ] )
確認するには、コレクションに対してクエリを実行します。
db.students.find()
次のdb.collection.updateOne()
操作は、集約パイプラインを使用してドキュメントを_id: 3
で更新します。
db.students.updateOne( { _id: 3 }, [ { $set: { "test3": 98, modified: "$$NOW"} } ] )
具体的には、パイプラインは $set
ステージで構成されます。このステージでは、test3
フィールドをドキュメントに追加(その値を 98
に設定)し、modified
フィールドを現在の日付時刻に設定します。この操作では、現在の日時の集計変数NOW
が使用されます。変数にアクセスするには、先頭に$$
を付けて引用符で囲みます。
更新を確認するには、コレクションにクエリすることができます。
db.students.find().pretty()
updateMany と $replaceRoot および $set
students2
コレクションの例えを作成します(コレクションが現在存在しない場合は、挿入操作でコレクションが作成されます)。
db.students2.insertMany( [ { "_id" : 1, quiz1: 8, test2: 100, quiz2: 9, modified: new Date("01/05/2020") }, { "_id" : 2, quiz2: 5, test1: 80, test2: 89, modified: new Date("01/05/2020") }, ] )
確認するには、コレクションに対してクエリを実行します。
db.students2.find()
次の db.collection.updateMany()
オペレーションでは、集計パイプラインを使用してドキュメントのフィールドを標準化し(コレクション内のドキュメントには同じフィールドが必要です)、modified
フィールドを更新してください。
db.students2.updateMany( {}, [ { $replaceRoot: { newRoot: { $mergeObjects: [ { quiz1: 0, quiz2: 0, test1: 0, test2: 0 }, "$$ROOT" ] } } }, { $set: { modified: "$$NOW"} } ] )
具体的には、パイプラインは以下のように構成されています。
quiz1
、quiz2
、test1
およびtest2
フィールドにデフォルト値を設定する$mergeObjects
式を使用した$replaceRoot
ステージ。集計変数ROOT
は、現在変更されているドキュメントを参照します。変数にアクセスするには、先頭に$$
を付けて引用符で囲みます。現在のドキュメント フィールドがデフォルト値を上書きします。modified
フィールドを現在の日時で更新する$set
ステージ。この操作では、現在の日時の集計変数NOW
が使用されます。変数にアクセスするには、先頭に$$
を付けて引用符で囲みます。
更新を確認するには、コレクションにクエリすることができます。
db.students2.find()
updateMany と $set
students3
コレクションの例えを作成します(コレクションが現在存在しない場合は、挿入操作でコレクションが作成されます)。
db.students3.insertMany( [ { "_id" : 1, "tests" : [ 95, 92, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "tests" : [ 94, 88, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 3, "tests" : [ 70, 75, 82 ], "modified" : ISODate("2019-01-01T00:00:00Z") } ] );
確認するには、コレクションに対してクエリを実行します。
db.students3.find()
次の db.collection.updateMany()
オペレーションでは、集計パイプラインを使用して、計算された平均成績とレターグレードでドキュメントを更新します。
db.students3.updateMany( { }, [ { $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] }, modified: "$$NOW" } }, { $set: { grade: { $switch: { branches: [ { case: { $gte: [ "$average", 90 ] }, then: "A" }, { case: { $gte: [ "$average", 80 ] }, then: "B" }, { case: { $gte: [ "$average", 70 ] }, then: "C" }, { case: { $gte: [ "$average", 60 ] }, then: "D" } ], default: "F" } } } } ] )
具体的には、パイプラインは以下のように構成されています。
tests
配列エレメントの切り捨てられた平均値を計算し、modified
フィールドを現在の DateTime にアップデートする$set
ステージ。切り捨てられた平均を計算するために、ステージは$avg
式と$trunc
式を使用します。この操作では、現在の日時の集計変数NOW
が使用されます。変数にアクセスするには、先頭に$$
を付けて引用符で囲みます。
更新を確認するには、コレクションにクエリすることができます。
db.students3.find()
updateOne と $set
students4
コレクションの例えを作成します(コレクションが現在存在しない場合は、挿入操作でコレクションが作成されます)。
db.students4.insertMany( [ { "_id" : 1, "quizzes" : [ 4, 6, 7 ] }, { "_id" : 2, "quizzes" : [ 5 ] }, { "_id" : 3, "quizzes" : [ 10, 10, 10 ] } ] )
確認するには、コレクションに対してクエリを実行します。
db.students4.find()
次の db.collection.updateOne()
オペレーションでは、集計パイプラインを使用して _id:
2
のクイズ得点をドキュメントに追加します。
db.students4.updateOne( { _id: 2 }, [ { $set: { quizzes: { $concatArrays: [ "$quizzes", [ 8, 6 ] ] } } } ] )
更新を確認するには、コレクションにクエリします。
db.students4.find()
updateMany と $addFields
摂氏単位の温度を含むサンプル temperatures
コレクションを作成します(コレクションが現在存在しない場合は、挿入操作によってコレクションが作成されます)。
db.temperatures.insertMany( [ { "_id" : 1, "date" : ISODate("2019-06-23"), "tempsC" : [ 4, 12, 17 ] }, { "_id" : 2, "date" : ISODate("2019-07-07"), "tempsC" : [ 14, 24, 11 ] }, { "_id" : 3, "date" : ISODate("2019-10-30"), "tempsC" : [ 18, 6, 8 ] } ] )
確認するには、コレクションに対してクエリを実行します。
db.temperatures.find()
次のdb.collection.updateMany()
操作では、集計パイプラインを使用して、対応する華氏温度でドキュメントを更新します。
db.temperatures.updateMany( { }, [ { $addFields: { "tempsF": { $map: { input: "$tempsC", as: "celsius", in: { $add: [ { $multiply: ["$$celsius", 9/5 ] }, 32 ] } } } } } ] )
具体的には、パイプラインは $addFields
ステージで構成され、華氏単位の温度を含む新しい配列フィールド tempsF
を追加します。tempsC
配列内の各摂氏温度を華氏に変換するために、ステージでは$map
式を$add
および$multiply
式とともに使用します。
更新を確認するには、コレクションにクエリすることができます。
db.temperatures.find()
let 変数を使用した更新
バージョン 5.0 で追加
コマンド内の他の場所からアクセスできる変数を定義するには、 letオプションを使用します。
注意
変数を使用して結果をフィルタリングするには、$expr
演算子内の変数にアクセスする必要があります。
コレクション cakeFlavors
を以下ように作成します。
db.cakeFlavors.insertMany( [ { _id: 1, flavor: "chocolate" }, { _id: 2, flavor: "strawberry" }, { _id: 3, flavor: "cherry" } ] )
次のupdateOne
コマンドは、 let
オプションで設定された変数を使用します。
targetFlavor
変数はcherry
に設定されます。この変数は、一致フィルターを指定するために$eq
式で使用されます。newFlavor
変数はorange
に設定されます。この変数は、一致したドキュメントの更新されたflavor
値を指定するために$set
演算子で使用されます。
db.cakeFlavors.updateOne( { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, [ { $set: { flavor: "$$newFlavor" } } ], { let: { targetFlavor: "cherry", newFlavor: "orange" } } )
上記の更新操作を実行すると、 cakeFlavors
コレクションには次のドキュメントが含まれます。
[ { _id: 1, flavor: 'chocolate' }, { _id: 2, flavor: 'strawberry' }, { _id: 3, flavor: 'orange' } ]
その他の例
その他の例えについては、さまざまなアップデート方法のページも参照してください。