Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs Menu
Docs Home
/ / /
Go Driver
/

BSON との連携

このガイドでは、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

フィールドのタイプが、int64uintuint32、またはuint64で、フィールドの値が符号付き int32に収まる場合、フィールドは BSON int64ではなく BSON int32としてシリアル化されます。値が符号付きint32に収まらない場合、このタグは無視されます。

truncate

フィールドタイプが float 数値型でない場合、そのフィールドにマーシャリングされていない BSON 倍数は小数点で切り捨てられます。

inline

フィールドタイプが構造体フィールドまたはマップ フィールドの場合、フィールドはマーシャリング時にフラット化され、アンマーシャリング時にフラット化が解除されます。

struct タグを指定しない場合、Go ドライバーは次のルールを使用して構造体をマーシャリングします。

  1. ドライバーはエクスポートされたフィールドのみをマーシャリングおよびアンマーシャリングします。

  2. ドライバーは、対応する構造体フィールドの小文字を使用して BSON キーを生成します。

  3. ドライバーは埋め込まれた構造体フィールドをサブドキュメントとしてマーシャリングします。各キーは、フィールドタイプの小文字です。

  4. ポインターが nil 以外の場合、ドライバはポインターフィールドを基礎の型としてマーシャリングします。ポインターが nil の場合、ドライバーは BSON null 値としてマーシャリングします。

  5. 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 オプションを指定して、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(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.Marshal() メソッドと bson.Unmarshal() メソッドでは、 bson.D 型など、 BSONドキュメントにエンコードできるパラメータが必要です。誤った型を渡すと、Write エラーが発生します。例、bson.Marshal() に string を渡すと、WriteString エラーが発生します。

次のコードは、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ドキュメント全体をアン マーシャリングせずに個々の要素を検索できます。Raw タイプの使用方法の詳細については、Raw BSONデータの操作 セクションを参照してください。

To learn more about the marshalling and unmarshalling methods used with the Cursor type, see the Cursor API documentation.

To learn more about the marshalling and unmarshalling methods in the bson package, see the bson API documentation.

Goドライバーは、Raw タイプを通じて未加工のBSONドキュメントの操作をサポートしています。Raw 型を使用すると、 BSONドキュメント全体をアン マーシャリングせずに、バイトのスライスから要素を検証して取得できます。これは、次の状況で役立ちます。

  • ドキュメント全体を変換せずに特定のフィールドで検索を実行

  • ドキュメント全体のアンマーシャリングを回避することでメモリのオーバーヘッドを削減

  • データベースから受信したバイナリBSONデータを直接操作

Raw 型は、 BSONドキュメントを検証し、キーで個々の要素を検索するメソッドを提供します。次の例は、未加工のBSONドキュメントを検証し、そのドキュメントから特定のフィールドを検索する方法を示しています。

collection := client.Database("sample_restaurants").Collection("restaurants")
findOptions := options.FindOne()
var raw bson.Raw
err = collection.FindOne(
context.TODO(),
bson.D{{"name", "Mongo's Pizza"}},
findOptions,
).Decode(&raw)
if err != nil {
log.Fatalf("Failed to find document: %v", err)
}
// Print the document type
fmt.Printf("Document type: %T\n", raw)
// Access a field from the raw document
name := raw.Lookup("name").StringValue()
fmt.Println("Restaurant name:", name)
Document type: bson.Raw
Restaurant name: Mongo's Pizza

To learn more about the Raw family of types, see the Raw BSON API documentation.

戻る

構造タグを使用する

項目一覧