ここでのプロセスは非常に単純で、配列内の要素を「検索または作成」する場所によってのみ異なります。
まず、各キーの要素がすでに配置されていると仮定すると、単純なケースは、要素をクエリし、位置$
演算子:
db.collection.update(
{
"_id": docId,
"attrs": { "$elemMatch": { "key": "A1", "type": "T1" } }
}
{ "$set": { "attrs.$.value": "20" }
)
これにより、他の要素に影響を与えることなく、一致する要素のみが変更されます。
「検索または作成」が必要で、特定のキーが存在しない可能性がある2番目のケースでは、「2つの」更新ステートメントを使用します。ただし、 Bulk Operations API 単一の応答でサーバーへの単一の要求でこれを行うことができます:
var bulk = db.collection.initializeOrderedBulkOp();
// Try to update where exists
bulk.find({
"_id": docId,
"attrs": { "$elemMatch": { "key": "A1", "type": "T2" } }
}).updateOne({
"$set": { "attrs.$.value": "30" }
});
// Try to add where does noes not exist
bulk.find({
"_id": docId,
"attrs": { "$not": { "$elemMatch": { "key": "A1", "type": "T2" } } }
}).updateOne({
"$push": { "attrs": { "key": "A1", "type": "T2", "value": "30" } }
});
bulk.execute();
基本的なロジックは、最初に更新が試行され、前と同じように要素が必要な値と一致するようにすることです。他の条件は、 $not
。
配列要素が見つからなかった場合は、 $push
。
ここでは特に否定的な一致を探しているので、更新する予定の「ドキュメント」を_id
などの一意の識別子で一致させることをお勧めします。 鍵。 「マルチ」アップデートでは可能ですが、何をしているかに注意する必要があります。
したがって、「検索または作成」プロセスを実行する場合、一致しなかった要素が他の要素に干渉することなく配列に正しく追加され、予想される一致の以前の更新も同じ方法で適用されます。
>{
"_id" : ObjectId("55b570f339db998cde23369d"),
"attrs" : [
{
"key" : "A1",
"type" : "T1",
"value" : "20"
},
{
"key" : "A2",
"type" : "T2",
"value" : "14"
},
{
"key" : "A1",
"type" : "T2",
"value" : "30"
}
]
}
これは従うべき単純なパターンです。もちろん、ここでの一括操作は、サーバーとの間で複数の要求を送受信することに伴うオーバーヘッドを取り除きます。これらはすべて、存在する場合も存在しない場合もある他の要素に干渉することなく、うまく機能します。
それとは別に、要素をトラバースするためにJavaScriptサーバー処理に戻る必要なしに、標準の演算子でサポートされているように、クエリと分析を容易にするためにデータを配列に保持するという追加の利点があります。