Docs Menu
Docs Home
/ /

データモデリングと直列化

このガイドでは、Rust ドライバーが BSON 型と Rust 型の間の変換を処理する方法について学習できます。 Rust 型を BSON に変換するプロセスは直列化 と呼ばれ、その逆のプロセスは 逆直列化 と呼ばれます。

Rust言語は静的型システムを使用しますが、 BSON には 動的スキーマがあります。Rust型とBSONの間の変換を処理するために、ドライバーと BSON crate はSerdeフレームワークの機能を統合します。

Tip

bson crateは mongodb crateとともにエクスポートされます。serdecrateをインストールする方法については、 crates.iocrateレジストリの serde を参照してください。

serde crate の機能をアプリケーションに実装することで、構造体や列挙型などのカスタム Rust 型を使用してデータをモデル化できます。

このガイドには、次のセクションが含まれています。

  • ジェネリック型パラメーターでは、コレクションのパラメーター化とデータ モデリングについて説明します

  • カスタム データ モデルでは、コレクション内のデータをモデル化するためにカスタム Rust タイプを定義する方法について説明します。

  • カスタム直列化では、属性を使用してデフォルトの直列化および逆直列化の動作を変更する方法について説明し、例を示します

  • 追加情報では、このガイドで言及されている型とメソッドのリソースとAPIドキュメントへのリンクを提供します

Collectionインスタンスを作成するときは、コレクション内のドキュメントをモデル化するデータ型を表すジェネリック型パラメータを指定する必要があります。 ジェネリック型パラメータの指定の詳細については、「 データベースとコレクション 」ガイドのコレクション パラメータ化 」セクションを参照してください。

コレクションのデータをモデル化するには、 Document型を使用する代わりに、カスタム タイプを定義して使用することを推奨します。

serde crate からのSerializeDeserializeの追尾を実装する Rust データ型は、 Collectionインスタンスのジェネリック型パラメータとして使用できます。 SerializeDeserializeの特権を実装するには、Rust タイプを定義する前に次のderive属性を含める必要があります。

#[derive(Serialize, Deserialize)]

次のコードは、 serde直列化特性を実装するサンプルArticle構造体を定義します。

#[derive(Serialize, Deserialize)]
struct Article {
title: String,
date: DateTime,
content: String,
content_embeddings: Vector,
}

Tip

ベクトル型

bson ライブラリ v2.14 以降、bson::binary::Vector 型を使用して、数値のベクトルを表すことができます。

この型はBSONバイナリベクトルとしてシリアル化されるため、Vector を使用するとストレージ効率が向上します。詳細については、BSON仕様 を参照してください。

次のコードは、Article 構造体をジェネリック型パラメータとして使用して articlesコレクションにアクセスします。

let my_coll: Collection<Article> = client
.database("db")
.collection("articles");

CollectionインスタンスはArticle 構造体でパラメータ化されているため、このタイプでCRUD操作を実行できます。次のコードは、Articleインスタンスをコレクションに挿入します。

let article = Article {
title: "Maintaining Your Garden in Winter".to_string(),
date: DateTime::now(),
content: "As fall winds down, you might be wondering what you should be doing in your garden in the coming months ...".to_string(),
content_embeddings: Vector::Float32(vec! [0.01020927,-0.011224265,0.015686288,-0.018586276,-0.023160344])
};
my_coll.insert_one(article).await?;

コレクションに複数のスキーマが含まれている場合は、各データ型をモデル化するためのカスタムタイプを定義し、各型の元のCollectionインスタンスのクローンを作成できます。 clone_with_type()メソッドを使用して、 Collectionインスタンスのクローンを作成できます。

最初にSquareという構造体でコレクションをパラメータ化していても、その後、 Circle構造体でモデル化された別のタイプのデータをコレクションに挿入したいと認識したとします。 次のコードでは、 Square型のコレクションをパラメータ化し、 Circle型でパラメータ化されたコレクションのクローンを作成します。

let shapes_coll: Collection<Square> = client
.database("db")
.collection("shapes");
// ... perform some operations with Square
let shapes_coll: Collection<Circle> = shapes_coll.clone_with_type();
// ... perform some operations with Circle

Rust ドライバーのデフォルトの直列化および逆直列化動作は、 serde crate の属性を使用して変更できます。 属性は、列挙型の構造体またはバリアントのフィールドに添付される任意のメタデータです。

serde crate は、ヘルパー関数を値として受け取るserialize_withdeserialize_withの属性を提供します。 これらのヘルパー関数は、特定のフィールドとバリアントの直列化と逆直列化をカスタマイズします。 フィールドに属性を指定するには、フィールド定義の前に属性を含めます。

#[derive(Serialize, Deserialize)]
struct MyStruct {
#[serde(serialize_with = "<helper function>")]
field1: String,
// ... other fields
}

次のセクションでは、bson ライブラリのヘルパー型を使用して一般的な直列化タスクを実行する例を見つけることができます。

例では、次のアプローチが示されています。

  • BSON 3.0:serde_with crateが提供する serde_as アノテーションを使用することで、柔軟性と構成機能が向上します

  • BSON 2.x:従来の serialize_withヘルパー関数を使用します

BSON 2.15 がデフォルトのバージョンです。BSON crateバージョンに一致するアプローチを選択します。

アプリケーションでBSON 3.0 を使用するには、次のようにプロジェクトの Cargo.toml で機能として有効にします。

[dependencies.mongodb]
version = "3.3.0"
features = ["bson-3"]

BSON 3.0 を有効にすると、serde_as を使用できます。serde_as を使用するには、次のコードに示すように、アプリケーションにそれをインポートする必要があります。

use serde_with::serde_as;

Serdeヘルパー関数の完全なリストを確認するには、serde_helpers APIドキュメントを参照してください。

構造体でドキュメント内の _idフィールドを16進数文字列として表現する場合があります。16進数文字列 をObjectId BSONタイプに変換するには、 BSON crateバージョンに応じて対応するコード例の BSON 3.0 (serde_as) タブまたは BSON 2.x (serialize_with)タブを選択します。

serde_as アノテーションとともに bson::serde_helpers::object_id::FromHexString 型を使用する。

#[serde_as]
#[derive(Serialize, Deserialize)]
struct Order {
#[serde_as(as = "object_id::FromHexString")]
_id: String,
item: String,
}

serialize_hex_string_as_object_idヘルパー関数を使用します。

#[derive(Serialize, Deserialize)]
struct Order {
#[serde(serialize_with = "serialize_hex_string_as_object_id")]
_id: String,
item: String,
}

ドライバーがサンプルのOrder 構造体を BSON に直列化する方法を確認するには、次のStruct タブとBSON タブから選択します。

let order = Order {
_id: "6348acd2e1a47ca32e79f46f".to_string(),
item: "lima beans".to_string(),
};
{
"_id": { "$oid": "6348acd2e1a47ca32e79f46f" },
"item": "lima beans"
}

BSONでは、ドキュメント内の DateTimeフィールド値を ISO 形式のstringとして表現する場合があります。この変換に対応するコード例については、BSON 3.0(serde_as) タブまたは BSON 2.x (serialize_with)タブを選択します。

serde_as アノテーションとともに bson::serde_helpers::datetime::AsRfc3339String 型を使用する。

#[serde_as]
#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde_as(as = "datetime::AsRfc3339String")]
delivery_date: DateTime,
}

serialize_bson_datetime_as_rfc3339_stringヘルパー関数を使用します。

#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde(serialize_with = "serialize_bson_datetime_as_rfc3339_string")]
delivery_date: DateTime,
}

BSON 3.0(serde_as)またはBSON 2.x (serialize_with)のタブを選択して、ドライバーがサンプルのOrder構造体をBSONに直列化する方法を確認します。

let order = Order {
item: "lima beans".to_string(),
delivery_date: DateTime::now(),
};
{
"_id": { ... },
"item": "lima beans",
"delivery_date": "2023-09-26T17:30:18.181Z"
}

BSONでは、ドキュメント内の u32フィールド値を f64 または Double のタイプとして表現する場合があります。この変換を指定するには、対応するコード サンプルの BSON 3.0(serde_as) タブまたは BSON 2.x (serialize_with)タブを選択します。

serde_as アノテーションとともに bson::serde_helpers::u32::AsF64 型を使用する。

#[serde_as]
#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde_as(as = "u32::AsF64")]
quantity: u32,
}

serialize_u32_as_f64ヘルパー関数を使用します。

#[derive(Serialize, Deserialize)]
struct Order {
item: String,
#[serde(serialize_with = "serialize_u32_as_f64")]
quantity: u32,
}

注意

u32値の BSON Double表現は、元の値と同じように表示されます。

ヘルパー関数に加えて、 bsonライブラリは直列化と逆直列化の両方を取り扱うモジュールを提供します。 特定のフィールドまたはバリアントで使用するモジュールを選択するには、 with属性の値をモジュールの名前に設定します。

#[derive(Serialize, Deserialize)]
struct MyStruct {
#[serde(with = "<module>")]
field1: u32,
// ... other fields
}

これらのモジュールの完全なリストについては、serde_helpers APIドキュメント を参照してください。

serde crateは、シリアル化をカスタマイズするための他の多くの属性を提供します。 次のリストでは、一般的な属性とその機能について説明しています。

  • rename: Rust 構造体またはバリアント名の代わりに、指定された名前でフィールドを直列化および逆直列化します

  • skip: 指定されたフィールドをシリアル化または逆シリアル化しない

  • default: 逆シリアル化中に値が存在しない場合は、 のデフォルト値を使用します Default::default()

serde 属性の完全なリストについては、serde 属性APIドキュメントを参照してください。

BSON typesの詳細については、サーバー マニュアルの「 BSON types 」を参照してください。

serde機能を示すその他の例については、「 Rust 開発者センターでサーデを使用してデータを構造化する」に関する記事を参照してください。

Serdeフレームワークの詳細については、 Serde のドキュメント を参照してください。

このガイドで言及されているメソッドとタイプの詳細については、次のAPIドキュメントを参照してください。

戻る

チュートリアル: CRUD Web アプリ

項目一覧