$addFields(集計)
定義
$addFields
ドキュメントに新しいフィールドを追加します。
$addFields
は、入力ドキュメントの既存の全フィールドと、新しく追加されたフィールドを含むドキュメントを出力します。$addFields
ステージは、入力ドキュメント内のすべての既存フィールドを明示的に指定し、新しいフィールドを追加する$project
ステージと同等です。注意
$addFields
のエイリアスである$set
ステージを使用することもできます。
互換性
次の環境でホストされる配置には $addFields
を使用できます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
構文
このステージの構文は、次のとおりです。
{ $addFields: { <newField>: <expression>, ... } }
追加する各フィールドの名前を指定し、その値を集計式または空のオブジェクトに設定します。式の詳細については、「式演算子」を参照してください。
重要
新しいフィールドの名前が既存のフィールド名(_id
など)と同じ場合、$addFields
はそのフィールドの既存の値を、指定された式の値で上書きします。
動作
$addFields
既存のドキュメントに新しいフィールドを追加します。集計操作には 1 つ以上の$addFields
ステージを含めることができます。$addFields
は、集計式または空のオブジェクトに値を設定できるオブジェクトの埋め込みを受け入れます。たとえば、以下のようなネストされたオブジェクトを受け入れられます。{$addFields: { a: { b: { } } } } 埋め込みドキュメント (配列内のドキュメントを含む) に 1 つまたは複数のフィールドを追加するには、ドット表記を使用します。 例 を参照してください。
$addFields
を使用して既存の配列フィールドに要素を追加するには、$concatArrays
を使用します。例を参照してください。
例
2 つの$addFields
ステージを使用します
scores
というコレクションには次のドキュメントが含まれています。
db.scores.insertMany( [ { _id: 1, student: "Maya", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0 }, { _id: 2, student: "Ryan", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8 } ] )
次の操作では、2 つの$addFields
ステージを使用して、出力ドキュメントに 3 つの新しいフィールドを含めます。
db.scores.aggregate( [ { $addFields: { totalHomework: { $sum: "$homework" } , totalQuiz: { $sum: "$quiz" } } }, { $addFields: { totalScore: { $add: [ "$totalHomework", "$totalQuiz", "$extraCredit" ] } } } ] )
この操作により、次のドキュメントが返されます。
[ { _id: 1, student: "Maya", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0, totalHomework: 25, totalQuiz: 18, totalScore: 43 }, { _id: 2, student: "Ryan", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8, totalHomework: 16, totalQuiz: 16, totalScore: 40 } ]
埋め込みドキュメントへのフィールドの追加
埋め込みドキュメントに新しいフィールドを追加するには、ドット表記を使用します。
たとえば、次のドキュメントを含む vehicles
というコレクションを作成します。
db.vehicles.insertMany( [ { _id: 1, type: "car", specs: { doors: 4, wheels: 4 } }, { _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2 } }, { _id: 3, type: "jet ski" } ] )
次の集計操作は、埋め込みドキュメント specs
に新しいフィールド fuel_type
を追加します。
db.vehicles.aggregate( [ { $addFields: { "specs.fuel_type": "unleaded" } } ] )
この操作は次の結果を返します。
[ { _id: 1, type: "car", specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } }, { _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } }, { _id: 3, type: "jet ski", specs: { fuel_type: "unleaded" } } ]
既存のフィールドの上書き
$addFields
操作で既存のフィールド名を指定すると、元のフィールドが置き換えられます。
animals
というコレクションには次のドキュメントが含まれています。
db.animals.insertOne( { _id: 1, dogs: 10, cats: 15 } )
次の $addFields
操作では、 cats
フィールドを指定します。
db.animals.aggregate( [ { $addFields: { cats: 20 } } ] )
この操作を実行すると次のドキュメントが返されます。
[ { _id: 1, dogs: 10, cats: 20 } ]
あるフィールドを別のフィールドで置き換えることができます。次の例では、_id
フィールドの代わりに item
フィールドを使用します。
fruit
というコレクションには次のドキュメントが含まれています。
db.fruit.insertMany( [ { _id: 1, item: "tangerine", type: "citrus" }, { _id: 2, item: "lemon", type: "citrus" }, { _id: 3, item: "grapefruit", type: "citrus" } ] )
次の集計操作では、$addFields
を使用して各ドキュメントの _id
フィールドを item
フィールドの値に置き換え、item
フィールドを静的な値に置き換えます。
db.fruit.aggregate( [ { $addFields: { _id : "$item", item: "fruit" } } ] )
この操作では、以下を返します。
[ { _id: "tangerine", item: "fruit", type: "citrus" }, { _id: "lemon", item: "fruit", type: "citrus" }, { _id: "grapefruit", item: "fruit", type: "citrus" } ]
配列への要素の追加
次のように、サンプル scores
コレクションを作成します。
db.scores.insertMany( [ { _id: 1, student: "Maya", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0 }, { _id: 2, student: "Ryan", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8 } ] )
$addFields
と$concatArrays
式を併用して、既存の配列フィールドに要素を追加できます。 たとえば、次の操作では、 $addFields
を使用して、 homework
フィールドを、現在のhomework
配列が新しいスコア[ 7 ]
を含む別の配列に連結されている新しい配列に置き換えます。
db.scores.aggregate( [ { $match: { _id: 1 } }, { $addFields: { homework: { $concatArrays: [ "$homework", [ 7 ] ] } } } ] )
この操作では、以下を返します。
[ { _id: 1, student: "Maya", homework: [ 10, 5, 10, 7 ], quiz: [ 10, 8 ], extraCredit: 0 } ]
removeFields
$$REMOVE
変数で $addFields
を使用すると、ドキュメント フィールドを削除できます。
たとえば、labReadings
コレクションを作成します。
db.labReadings.insertMany( [ { date: ISODate("2024-10-09"), temperature: 80 }, { date: null, temperature: 83 }, { date: ISODate("2024-12-09"), temperature: 85 } ] )
labReadings
ドキュメントから date
フィールドを削除するには、$$REMOVE
変数で $addFields
を使用します。
db.labReadings.aggregate( [ { $addFields: { date: "$$REMOVE" } } ] )
出力:
[ { _id: ObjectId('671285306fd2c3b24f2e7eaa'), temperature: 80 }, { _id: ObjectId('671285306fd2c3b24f2e7eab'), temperature: 83 }, { _id: ObjectId('671285306fd2c3b24f2e7eac'), temperature: 85 } ]
$$REMOVE
を使用して条件付きでフィールドを削除することもできます。たとえば、次の集計では、date
が null
であるドキュメントから date
フィールドが削除されます。
db.labReadings.aggregate( [ { $addFields: { date: { $ifNull: [ "$date", "$$REMOVE" ] } } } ] )
出力:
[ { _id: ObjectId('671285306fd2c3b24f2e7eaa'), date: ISODate('2024-10-09T00:00:00.000Z'), temperature: 80 }, { _id: ObjectId('671285306fd2c3b24f2e7eab'), temperature: 83 }, { _id: ObjectId('671285306fd2c3b24f2e7eac'), date: ISODate('2024-12-09T00:00:00.000Z'), temperature: 85 } ]
Tip
$project との比較
ドキュメントフィールドを削除するには、$addFields
または $project
ステージを使用できます。最適なアプローチは、パイプラインと、元のドキュメントをどれだけ保持するかによって異なります。
$project
ステージで $$REMOVE
を使用する例については、「条件付きでのフィールドの除外」を参照してください。