BSON との連携
Overview
このガイドでは、Go ドライバーが BSON 型と Go 型の間の変換を処理する方法について学習できます。Go 型を BSON に変換するプロセスはマーシャリングと呼ばれ、その逆のプロセスは アン マーシャリングと呼ばれます。
次のセクションでは、Go ドライバーが BSON データを表す方法と、デフォルトのマーシャリングおよびアン マーシャリング動作を調整する方法について説明します。
データ型
MongoDB では、BSON と呼ばれるバイナリ形式でドキュメントを保存することで、簡単かつ柔軟なデータ処理を可能にしています。
Go ドライバーは、BSON データを操作するための 4 つの主要なタイプを提供します。
D
:BSON ドキュメント(スライス)の順序付けられた表現M
:BSON ドキュメント(マップ)の順序付けられていない表現A
:BSON 配列の順序付けられた表現E
:D 型内部の 1 つの要素
以下の例では、bson.D
タイプを使用してクエリフィルターを作成し、quantity
フィールドの値が 100 より大きいドキュメントに一致させる方法を示しています。
filter := bson.D{{"quantity", bson.D{{"$gt", 100}}}}
GoドライバーがBSONデータを処理する方法の詳細については、「 bsonパッケージAPIドキュメント 」を参照してください。
構造タグ
Go では、構造体はデータ型が宣言されたデータフィールドの集まりです。構造体フィールドにおけるデフォルトのマーシャリングおよびアン マーシャリング動作は、構造体フィールドに添付される任意のメタデータである構造体タグを使用して変更できます。構造体タグの最も一般的な用途は、構造体フィールドに対応する BSON ドキュメント内のフィールド名を指定することです。次の表では、Go ドライバーで使用できる追加の構造体タグについて説明します。
構造体タグ | 説明 |
---|---|
omitempty | フィールドタイプに対応するゼロ値が設定されている場合、フィールドはマーシャリングされません。 |
minsize | フィールドのタイプが、 int64 、uint 、uint32 、またはuint64 で、フィールドの値が符号付き int32 に収まる場合、フィールドは BSON int64 ではなく BSON int32 としてシリアル化されます。値が符号付きint32 に収まらない場合、このタグは無視されます。 |
truncate | フィールドタイプが float 数値型でない場合、そのフィールドにマーシャリングされていない BSON 倍数は小数点で切り捨てられます。 |
inline | フィールドタイプが構造体フィールドまたはマップ フィールドの場合、フィールドはマーシャリング時にフラット化され、アンマーシャリング時にフラット化が解除されます。 |
struct タグを指定しない場合、Go ドライバーは次のルールを使用して構造体をマーシャリングします。
ドライバーはエクスポートされたフィールドのみをマーシャリングおよびアンマーシャリングします。
ドライバーは、対応する構造体フィールドの小文字を使用して BSON キーを生成します。
ドライバーは埋め込まれた構造体フィールドをサブドキュメントとしてマーシャリングします。各キーは、フィールドタイプの小文字です。
ポインターが nil 以外の場合、ドライバはポインターフィールドを基礎の型としてマーシャリングします。ポインターが nil の場合、ドライバーは BSON null 値としてマーシャリングします。
Go ドライバーはマーシャリング時に、
interface{}
型フィールドでこれらの D/M 型マッピングに従います。このドライバーでは、interface{}
フィールドにアンマーシャルされた BSON ドキュメントをD
型としてアンマーシャリングします。
次の例は、Go ドライバーがさまざまな構造体タグを使用して構造体をマーシャリングする方法を示しています。
type Address struct { Street string City string State string } type Student struct { FirstName string `bson:"first_name,omitempty"` LastName string `bson:"last_name,omitempty"` Address Address `bson:"inline"` Age int } coll := client.Database("db").Collection("students") address1 := Address{ "1 Lakewood Way", "Elwood City", "PA" } student1 := Student{ FirstName : "Arthur", Address : address1, Age : 8} _, err = coll.InsertOne(context.TODO(), student1)
対応する BSON 表現は次のようになります。
{ "_id" : ObjectId("..."), "first_name" : "Arthur", "street" : "1 Lakewood Way", "city" : "Elwood City", "state" : "PA", "age" : 8 }
この例では、構造体タグを使用してドライバーを作成します。
のようなカスタム BSON フィールド名を設定します
first_name
空の
LastName
フィールドを削除しますネストされた構造体をフラット化し、すべてのフィールドを最上位レベルにします
次の例では、Go ドライバーが struct タグなしで構造体をマーシャリングする方法を示しています。
type Address struct { Street string City string State string } type Student struct { FirstName string LastName string Address Address Age int } coll := client.Database("db").Collection("students") address1 := Address{ "1 Lakewood Way", "Elwood City", "PA" } student1 := Student{ FirstName : "Arthur", Address : address1, Age : 8} _, err = coll.InsertOne(context.TODO(), student1)
対応する BSON 表現は次のようになります。
{ "_id" : ObjectId("..."), "firstname" : "Arthur", "lastname" : "", "address": { "street" : "1 Lakewood Way", "city" : "Elwood City", "state" : "PA" }, "age" : 8 }
struct タグがない場合、ドライバーは次のようになります。
構造体のフィールドの小文字を BSON フィールド名として設定します
空の
lastname
フィールドが含まれますAddress
フィールドをネストされた値として保存します
BSON オプション
BSON オプションを指定して、Client
インスタンスのマーシャリングおよびアンマーシャリングの動作を調整できます。Client
で BSON オプションを設定するには、 BSONOptions
インスタンスを作成および設定します。
この例では、次のアクションを実行します。
次の設定を構成して、
BSONOptions
インスタンスを作成します。UseJSONStructTags
フィールドをtrue
に設定し、"bson"
struct タグが指定されていない場合に"json"
struct タグを使用するようにドライバーに指示しますNilSliceAsEmpty
フィールドをtrue
に設定し、nil
Go スライスを空の BSON 配列としてマーシャリングするようにドライバーに指示します
BSONOptions
インスタンスをSetBSONOptions()
ヘルパー メソッドに渡して、ClientOptions
インスタンスを指定します指定された BSON マーシャリングおよびアン マーシャリング動作を適用するための
Client
を作成します
bsonOpts := &options.BSONOptions { UseJSONStructTags: true, NilSliceAsEmpty: true, } clientOpts := options.Client(). ApplyURI("<connection string>"). SetBSONOptions(bsonOpts) client, err := mongo.Connect(context.TODO(), clientOpts)
Tip
BSONOptions
の型の詳細については、「 BSONOptions API ドキュメント」を参照してください。BSONOptions
インスタンスを指定し、これらのオプションを使用してクライアントを作成する例については、「Connect() BSONOptions の例」を参照してください。
アン マーシャリング
BSON ドキュメントのマーシャリングを解除するには、FindOne
メソッドの結果または任意の *mongo.Cursor
インスタンスに対して Decode()
メソッドを使用します。
Decode()
メソッドは、以下のいずれかの値を含むerror
型を返します。
nil
ドキュメントがクエリと一致し、ドキュメントの取得およびアン マーシャリングでエラーが発生しなかった場合。ドライバーがドキュメントを取得したのに結果をアン マーシャリングできなかった場合、
Decode()
メソッドはアン マーシャリング エラーを返します。FindOne()
メソッドの実行中にドキュメントを取得する際にエラーが発生した場合、エラーはDecode()
メソッドに伝わり、Decode()
メソッドはエラーを返します。
FindOne()
メソッドによって返される SingleResult
型で使用すると、クエリフィルターに一致するドキュメントがない場合、Decode()
は ErrNoDocuments
エラーを返すこともできます。
次の例では、Decode()
メソッドを使用して単純な FindOne()
操作の結果をアン マーシャリングして読み取る方法を示しています。
coll := client.Database("db").Collection("students") filter := bson.D{{"age", 8}} var result bson.D err := coll.FindOne(context.TODO(), filter).Decode(&result) fmt.Println(result)
[{_id ObjectID("...")} {first_name Arthur} {street 1 Fern Way} {city Elwood City} {state PA} {age 8}]
Cursor
タイプは All()
メソッドも使用します。これは、カーソルに格納されているすべてのドキュメントを同時に配列にアン マーシャリングします。
bson
パッケージには、[]byte
タイプの BSON エンコード データを操作する Marshal()
メソッドと Unmarshal()
メソッドのファミリーが含まれています。
次のコードは、bson
パッケージのメソッドを使用して、BSON をユーザー定義の構造体にアン マーシャリングする方法を示しています。
type Item struct { Category string Quantity int32 } doc, err := bson.Marshal(bson.D{{"category", "plate"}, {"quantity", 6}}) var test Item err = bson.Unmarshal(doc, &test) fmt.Printf("Unmarshalled Struct:\n%+v\n", test)
Unmarshalled Struct: {Category:plate Quantity:6}
注意
Raw
タイプを使用すると、BSON ドキュメントのバイト スライスを Go 型にアン マーシャリングせずに要素を取得できます。このタイプを使用すると、BSON ドキュメント全体をアン マーシャリングせずに個々の要素を検索できます。
Cursor
型と併用されるマーシャリングとアンマーシャリング メソッドの詳細については、「カーソル API ドキュメント」を参照してください。
bson
パッケージでのマーシャリングとアンマーシャリング メソッドの詳細については、「bson API ドキュメント」を参照してください。