ドキュメント内の配列の更新
Overview
このガイドでは、1 つ以上のドキュメントの配列要素をアップデートする方法を学習できます。
配列内の要素を更新するには、次のアクションを実行します。
更新を指定する更新ドキュメントを入力します。
どの配列要素をアップデートするかを指定します。
これらの指定で更新操作を使用して更新を実行します。
サンプル データ
このガイドの例では、 drinks
コレクション内のドキュメントのモデルとして、次の Drink
構造体を使用します。
type Drink struct { Description string Sizes []int32 `bson:"sizes,truncate"` Styles []string }
truncate
構造体タグを使用すると、ドライバーはアンマーシャリング時にfloat64
などの型をint32
に切り捨てることができます。
このガイドの例を実行するには、次のスニペットを使用してサンプルデータをdb.drinks
コレクションにロードします。
coll := client.Database("db").Collection("drinks") docs := []interface{}{ Drink{Description: "Matcha Latte", Sizes: []int32{12, 16, 20}, Styles: []string{"iced", "hot", "extra hot"}}, } result, err := coll.InsertMany(context.TODO(), docs)
各ドキュメントには、各ドキュメントのdescription
、 sizes
、 styles
フィールドに対応する、飲み物の説明、利用可能なサイズ、利用可能な準備スタイルなど、飲み物の説明が含まれています。
Tip
存在しないデータベースとコレクション
書き込み操作を実行するときに必要なデータベースとコレクションが存在しない場合は、サーバーが暗黙的にそれらを作成します。
次の例では、 FindOneAndUpdate()
メソッドを使用してドキュメントを取得してアップデートし、アップデート後にドキュメントの状態を返します。 配列フィールドを使用して複数のドキュメントを更新する場合は、 UpdateMany()
メソッドを使用します。
配列要素の指定
アップデートする配列要素を指定するには、位置演算子を使用します。 位置演算子では、アップデートする最初の、複数の、またはすべての配列要素を指定でき 。
位置演算子を使用して配列要素を指定するには、ドット表記を使用します。 ドット表記は、埋め込みドキュメントの配列要素とフィールドを操作するためのプロパティ アクセス構文です。
最初の配列要素
クエリフィルターに一致する最初の配列要素を更新するには、位置指定の$
演算子を使用します。 配列フィールドでは、クエリフィルターは である必要があります。
例
この例では、次のアクションを実行します。
値が
16
以下のsizes
内の配列要素と一致します。一致する最初の配列値を
2
によって減算します。
filter := bson.D{{"sizes", bson.D{{"$lte", 16}}}} update := bson.D{{"$inc", bson.D{{"sizes.$", -2}}}} opts := options.FindOneAndUpdate(). SetReturnDocument(options.After) var updatedDoc Drink err := coll.FindOneAndUpdate(context.TODO(), filter, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(updatedDoc, false, false) fmt.Println(string(res))
{"description":"Matcha Latte","sizes":[10,16,20],"styles":["iced","hot","extra hot"]}
注意
クエリフィルターは、値12
と16
の値と一致します。 操作は最初に12
と一致するため、減算されます。 一致する値の両方をアップデートする場合は、「複数の配列要素 」を参照してください。
複数の配列要素
クエリフィルターに一致する複数の配列要素を更新するには、フィルタリングされた位置指定$[<identifier>]
演算子を使用します。 アップデート操作に配列フィルターを含めて、アップデートする配列要素を指定する必要があります。
<identifier>
は、配列フィルター内で使用する名前です。 この値は小文字で始まり、含めることができるのは英数字のみです。
例
この例では、次のアクションを実行します。
「ホット」を含む配列要素をマッチングするために、
hotOptions
という識別子を持つ配列フィルターを作成します。SetArrayFilters()
メソッドを使用して配列フィルターを適用します。これらの配列要素を削除します。
identifier := []interface{}{bson.D{{"hotOptions", bson.D{{"$regex", "hot"}}}}} update := bson.D{{"$unset", bson.D{{"styles.$[hotOptions]", ""}}}} opts := options.FindOneAndUpdate(). SetArrayFilters(options.ArrayFilters{Filters: identifier}). SetReturnDocument(options.After) var updatedDoc Drink err := coll.FindOneAndUpdate(context.TODO(), bson.D{}, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(updatedDoc, false, false) fmt.Println(string(res))
{"description":"Matcha Latte","sizes":[12,16,20],"styles":["iced","",""]}
すべての配列要素
すべての配列要素を更新するには、すべての位置指定$[]
演算子を使用します。
注意
配列フィールドにクエリフィルターを指定すると、位置指定の$[]
演算子はクエリフィルターを無視し、すべての配列要素を更新します。
例
この例では、 sizes
内のすべての配列要素に29.57
を掛けて、オンスからミリ秒に変換します。
update := bson.D{{"$mul", bson.D{{"sizes.$[]", 29.57}}}} opts := options.FindOneAndUpdate(). SetReturnDocument(options.After) var updatedDoc Drink err := coll.FindOneAndUpdate(context.TODO(), bson.D{}, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(updatedDoc, false, false) fmt.Println(string(res))
{"description":"Matcha Latte","sizes":[354,473,591],"styles":["iced","hot","extra hot"]}
詳細情報
このガイドで説明した操作の詳細については、次のガイドを参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。