MongoDBクエリ言語(MQL)で位置演算子を使用すると、配列を置き換えたり追加したりせずに、配列を含むドキュメントを で更新できます。
このチュートリアルでは、 MongoDB内の位置演算子のいくつかのユースケースを示します。
始める前に
mongoshをインストールします。
配置に接続します。
mongosh
を使用して、デフォルトのtest
データベース内の新しいコレクションにドキュメントを挿入します。db.employees.insertMany( [ { _id: 'SF', engineering: [ { name: 'Alice', email: 'missingEmail', salary: 100000 }, { name: 'Bob', email: 'missingEmail', salary: 75000 } ], sales: [ { name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 } ] }, { _id: 'NYC', engineering: [ { name: 'Dave', email: 'dave@mail.com', salary: 55000 }, ], sales: [ { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 }, { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 } ] } ] );
手順
次の例は、次の方法を示しています。
$ 演算子を使用して配列内の最初の一致を更新
配列内の最初の一致のみを更新するには、$
演算子を使用します。$
演算子は、一致した最初の要素をアップデートするためのプレースホルダーとして機能します。
次の例では、updateOne()
メソッドを $
演算子と $set
演算子とともに使用して、engineering
配列内の値が missingEmail
である最初のメールをalice@mail.com
に更新します。
1 db.employees.updateOne( 2 { "engineering.email": "missingEmail" }, 3 { "$set": { "engineering.$.email": "alice@mail.com" } } 4 );
find()
メソッドを使用して、Alice のメールへの更新を確認します。
db.employees.find()
[ { _id: 'SF', engineering: [ { name: 'Alice', email: 'alice@mail.com', salary: 100000 }, { name: 'Bob', email: 'missingEmail', salary: 75000 } ], sales: [ { name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 } ] }, { _id: 'NYC', engineering: [ { name: 'Dave', email: 'dave@mail.com', salary: 55000 } ], sales: [ { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 }, { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 } ] } ]
上記の例に示すように、配列要素があり、かつ engineering.email
フィールドが missingEmail
に設定されているドキュメントをフィルタリングすると、$
演算子はフィルターに一致する最初の出現のみをアップデートします。
$elemMatch と $ 演算子を使用した特定の要素の更新
特定の要素をアップデートするには、$elemMatch
演算子を使用します。
次の例では、$elemMatch
演算子と $
演算子を使用して、Bob の email
を "bob@mail.com"
に更新します。
1 db.employees.updateOne( 2 { engineering: { $elemMatch: { name: "Bob", email: "missingEmail" } } }, 3 { $set: { "engineering.$.email": "bob@mail.com" } } 4 );
find()
メソッドを使用して、 Bob のメールへの更新を確認します。
db.employees.find( { "engineering": { $elemMatch: { name: "Bob" } } }, { "engineering.$": 1, _id: 0 } );
[ { engineering: [ { name: 'Bob', email: 'bob@mail.com', salary: 75000 } ] } ]
$[] 演算子を使用してドキュメント内のすべての配列要素を更新
配列のすべての要素を 1 回の操作で更新するには、$[]
演算子を使用します。
ニューヨークの販売従業員に $2,000 の追加のビューを提供したいケースを考えてみましょう。updateMany()
$[]
演算子と$inc
演算子とともにbonus
sales
NYC
2000
メソッドを使用すると、 ドキュメント内の 配列内のすべての フィールドを ずつ増やすことができます。
1 db.employees.updateMany( 2 { "_id": "NYC" }, 3 { "$inc": { "sales.$[].bonus": 2000 } } 4 );
find()
メソッドを使用して、NYC の営業チーム従業員の bonus
フィールドへの更新を確認します。
db.employees.find( { _id: "NYC" }, { sales: 1, _id: 0 } );
[ { sales: [ { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 4000 }, { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 12000 } ] } ]
$[以前の識別子]<identifier> 演算子を使用して、フィルター条件に一致する要素を更新します
置換操作と組み合わせた過剰なクライアント側コードを使用せずに、1 回の操作で複数の配列要素を更新するには、$[<identifier>]
演算子を使用します。$[<identifier>]
演算子は、arrayFilters 条件に一致するすべての要素をアップデートするためのプレースホルダーとして機能します。
一定数の条件を満たす特定の従業員の給与を更新したいケースを考えてみましょう。updateMany()
$[<identifier>]
このタスクは、 演算子とともに メソッドで実行できます。
1 db.employees.updateMany( 2 {}, 3 { 4 "$set": { 5 "engineering.$[elemX].salary": 95000, 6 "sales.$[elemY].salary": 75000 7 } 8 }, 9 { 10 "arrayFilters": [ 11 { "elemX.name": "Bob", "elemX.salary": 75000 }, 12 { "elemY.name": "Ed", "elemY.salary": 50000, } 13 ] 14 } 15 );
上記の例では、最初のパラメーターは空の一致であり、コレクション内のすべてのドキュメントを評価します。
elemX
と elemY
は 2 つの異なる arrayFilter を表します。
elemX
を一致させるには、配列オブジェクトにname
フィールドがBob
で、かつsalary
フィールドが75000
である必要があります。elemY
を一致させるには、配列オブジェクトにname
フィールドがEd
で、かつsalary
フィールドが50000
である必要があります。
ドキュメント内の配列アイテムが elemX
フィルターに一致する場合、updateMany()
はオブジェクトの salary
フィールドを95000
に設定します。配列アイテムが elemY
フィルターに一致する場合、updateMany()
はオブジェクトの salary
フィールドを 75000
に設定します。フィルターが一致しない場合、対応する$set
操作はトリガーされません。
Bob は elemX
の条件の両方を満たしているため、find()
メソッドを使用して の給与の更新を確認します。
db.employees.find( { "engineering.name": "Bob" }, { engineering: { $elemMatch: { name: "Bob" } }, _id: 0 } );
[ { engineering: [ { name: "Bob", email: "bob@mail.com", salary: 95000 } ] } ]
find()
メソッドを使用して、Ed の給与への更新が成功しなかったことを確認するには、elemX
または elemY
の条件のいずれも満たしていないためです。
db.employees.find( { "sales.name": "Ed" }, { sales: { $elemMatch: { name: "Ed" } }, _id: 0 } );
[ { sales: [ { name: "Ed", email: "ed@mail.com", salary: 99000, bonus: 4000 } ] } ]
まとめ
このチュートリアルでは、 MongoDBクエリ言語(MQL)内のいくつかの位置演算子を説明します。これらの演算子は、配列を操作するときに便利です。配列や拡張クライアント側操作で完全な置換を行う必要がないためです。MQLの詳細については、Atlas の使用を参照してください。
MongoDBの更新演算子の詳細については、更新演算子を参照してください。