BSON types
BSON は MongoDB でドキュメントを保存し、リモート プロシージャ コールを行うために使用されるバイナリ直列化形式です。BSON の仕様は bsonspec.org に掲載されています。
各 BSON 型の識別子には、下表に示すとおり整数と文字列の両方があります。
タイプ | 番号 | エイリアス | ノート |
---|---|---|---|
Double | 1 | "double" | |
文字列 | 2 | "string" | |
オブジェクト | 3 | "object" | |
配列 | 4 | "array" | |
バイナリ データ | 5 | "binData" | |
未定義 | 6 | "undefined" | 非推奨。 |
ObjectId | 7 | "objectId" | |
ブール値 | 8 | "bool" | |
日付 | 9 | "date" | |
null | 10 | "null" | |
正規表現 | 11 | "regex" | |
DBポインタ | 12 | "dbPointer" | 非推奨。 |
JavaScript | 13 | "javascript" | |
シンボル | 14 | "symbol" | 非推奨。 |
32 ビット整数 | 16 | "int" | |
タイムスタンプ | 17 | "timestamp" | |
64 ビット整数 | 18 | "long" | |
Decimal128 | 19 | "decimal" | |
Min key | -1 | "minKey" | |
Max key | 127 | "maxKey" |
$type
演算子は、これらの値を使用してフィールドを BSON types でクエリすることをサポートします。$type
は、整数、小数点、double 型、および長整数 BSON types に一致するnumber
エイリアスもサポートしています。$type
集計演算子は、引数の BSON 型を返します。$isNumber
集計演算子は、引数が BSON 整数、小数点、double 型、長整数型の場合、true
を返します。
フィールドの型を確認するには、「型チェック」を参照してください。
BSON を JSON に変換する場合は、拡張 JSONに関する参考資料を参照してください。
以下の各セクションでは、特定の BSON types に関する特別な考慮事項を取りあげています。
バイナリ データ
BSON バイナリbinData
値はバイト配列です。 binData
値には、バイナリ データの解釈方法を示すサブタイプがあります。 次の表にサブタイプを掲げます。
番号 | 説明 |
---|---|
0 | 汎用バイナリのサブタイプ |
1 | 関数データ |
2 | バイナリ(旧) |
3 | UUID(旧) |
4 | UUID |
5 | MD5 |
6 | 暗号化された BSON 値 |
7 | 圧縮された時系列データ バージョン 5.2 で追加。 |
8 | キーやシークレットなどの機密データ。 MongoDB では、サブタイプ 8 のバイナリ データのリテラル値はログに記録されません。代わりに、MongoDB は |
9 | ベクトルデータとは、同じ型の数値が高密度に圧縮された配列です。 |
128 | カスタム データ |
ObjectId
ObjectId は小さく、ユニークである可能性が高く、生成が速く、順序付けられています。ObjectId の値は長さ 12 バイトで、次の要素で構成されます。
Unix エポックからの秒数で測定される ObjectId の作成を表す 4 バイトのタイムスタンプ。
クライアント側のプロセスごとに 1 回生成される 5 バイトのランダム値。このランダム値はマシンとプロセスに固有です。プロセスが再起動されるか、プロセスのプライマリノードが変更された場合、この値は再生成されます。
クライアント側プロセスごとの 3 バイトの増分カウンターで、ランダム値に初期化されます。プロセスが再起動すると、 カウンターはリセットされます。
タイムスタンプとカウンターの値では、最上位バイトがバイトシーケンスの最初に表示されます(ビッグエンディアン)。これは、再下位バイトが最初に表示される(リトルエンディアン)他の BSON 値との相違点です。
ObjectId の作成に整数値が使用される場合は、その整数がタイムスタンプに置き換わります。
MongoDBでは、標準コレクション内に保存される各ドキュメントには プライマリキーとして機能する一意の _idフィールドが必要です。_id
挿入されたドキュメントで フィールドが省略されている場合、 MongoDBドライバーは _id
フィールドの ObjectId を自動的に生成します。
上記は、アップサート: true に設定した更新操作を通じて挿入されるドキュメントにも適用されます。
MongoDB クライアントは、ユニークな ObjectId を持つ _id
フィールドを追加します。_id
フィールドに ObjectId を使用すると、次のような追加のメリットが得られます。
ObjectId
メソッドを使用して、mongosh
ObjectId.getTimestamp()
の 作成時間にアクセスできます。ObjectId は作成時間順におおよそ順序付けられますが、完全には順序付けられません。
ObjectId
値を含む_id
フィールドでコレクションをソートすることは、作成時間でソートすることとほぼ同等です。
ObjectId 値を設定、取得するには、ObjectId()
メソッドを使用します。
MongoDB 5.0 以降、mongosh
は、レガシーの mongo
shell を置き換えます。ObjectId()
メソッドは、mongosh
とレガシー shell の mongo
では異なる動作をします。レガシー メソッドの詳細については、「レガシー mongo Shell」を参照してください。
文字列
BSON 文字列は UTF-8 です。通常、各プログラミング言語のドライバーは、BSON の直列化と逆直列化時に、言語の文字列形式を UTF-8 に変換します。これにより、ほとんどの国際文字は BSON 文字列形式で簡単に保存できるようになります。[1]さらに、MongoDB $regex
クエリは正規表現文字列形式の UTF-8 をサポートしています。
[1] | UTF-8 文字セットを使用する文字列の場合、文字列に sort() を使用するのが無難です。ただし、内部的な sort() では C++ strcmp API を使用するため、ソート順序で一部の文字が誤って処理される場合があります。 |
タイムスタンプ
BSON には MongoDB 内部で使用される、通常の Date 型とは関連付けられていない特殊なタイムスタンプ型があります。この内部タイムスタンプ型は 64 ビット値であり、次の属性を持ちます。
最上位の 32 ビットは
time_t
値(UNIX エポックからの秒数)です。最下位 32 ビットは、指定された秒内の操作に対して増加していく
ordinal
です。
BSON 形式はリトルエンディアンであるため最下位ビットを最初に保存しますが、mongod
インスタンスは エンディアン属性にかかわらず、すべてのプラットフォームで ordinal
値の前に time_t
値を常に比較します。
レプリケーション中、oplog には ts
フィールドが生成され、BSON タイムスタンプ値を使用する optime を反映した値がこのフィールドに入ります。
単一のmongod
インスタンス内では、oplog内のタイムスタンプ値は常に一意です。
注意
BSON タイムスタンプ型は MongoDB 内部で使用するためのものです。アプリケーション開発では、BSON date 型を使用することがほとんどです。詳細については、「Date」を参照してください。
日付
BSON Date は、UNIX エポック(1970 年 1 月 1 日)以降のミリ秒数を表す 64 ビットの整数であり、過去から未来にわたって約 2 億 9000 万年の日付範囲を表現可能にします。
正規の BSON 仕様は BSON Date 型を UTC datetime として参照します。
BSON Date 型は符号付き整数です。[2] 負の値は 1970 年以前の日付を表します。
mongosh
で Date
を構築するには、new Date()
または ISODate()
コンストラクタを使用できます。
新しい Date() コンストラクターによる日付の構築
new Date()
コンストラクターを使用して Date
を構築するには、次のコマンドを実行します。
var mydate1 = new Date()
mydate1
変数は、 ISODateとしてラップされた日付と時刻を出力します。
mydate1
ISODate("2020-05-11T20:14:14.796Z")
ISODate() コンストラクターによる日付の構築
ISODate()
コンストラクターを使用して Date
を構築するには、次のコマンドを実行します。
var mydate2 = ISODate()
mydate2
変数には、 ISODateとしてラップされた日付と時刻が保存されます。
mydate2
ISODate("2020-05-11T20:14:14.796Z")
日付を string に変換する
Date
を string
形式で出力するには、toString()
メソッドを使用します。
mydate1.toString()
Mon May 11 2020 13:14:14 GMT-0700 (Pacific Daylight Time)
日付の月部分を返す
Date
値の月部分を返すこともできます。月はゼロからインデックス付けされます。そのため、1 月は月 0
です。
mydate1.getMonth()
4
[2] | バージョン 2.0 以前では、Date 値は符号なし整数として誤って解釈されていたため、Date フィールドのソート、範囲クエリ、インデックスに影響を及ぼしていました。インデックスはアップグレード時に再作成されないため、以前のバージョンで Date 値にインデックスを作成し、かつ 1970 年より前の日付がアプリケーションに関連する場合は、インデックスを再度作成してください。 |
decimal128
BSONデータ型
decimal128
は、小数の丸めが重要な場合に、非常に大きな数値または非常に正確な数値を保存するための 128 ビットの 10 進数表現です。浮動小数点のIEEE 754-2008 改訂の一環として 8 月 2009 に作成されました。 BSONデータ型の操作時に高精度が必要な場合は、decimal128
を使用する必要があります。
decimal128
34は、-6143 から + の指数範囲とともに6144 桁の精度の10進数、または有効桁数をサポートします。用語はdecimal128
標準では正規化されていないため、複数の可能な表現が可能です:10 x 10^-1 = 1 x 10^0 = .1 x 10^1 = .01 x 10^2
など。最大値と最小値をそれぞれ10^6144
と10^-6143
の順序で保存能力ため、次のことが可能になります。多くの精度。
コンストラクターで を使用するdecimal128
NumberDecimal()
MongoDBでは、NumberDecimal()
コンストラクターを使用して decimal128
形式でデータを保存できます。 10 進数値を string として渡すと、 MongoDB は次のようにデータベースに値を保存します。
NumberDecimal("9823.1297")
10 進数値を double
として渡すこともできます。
NumberDecimal(1234.99999999999)
また、プログラミング言語の decimal128
の使用状況とサポートも考慮する必要があります。次の言語はこの機能をネイティブでサポートしておらず、機能を取得するにはプラグインまたは追加のパッケージが必要です。
Python: decimal.Decimal モジュールは浮動小数点演算に使用できます。
Java: Java Billingクラスは
decimal128
数値のサポートを提供します。Node.js : js-big-decimal やnpmで利用可能なノード .js double decimal など、サポートを提供するパッケージがいくつかあります。
ユースケース
プログラムで数学計算を実行すると、予期しない結果が生じることがあります。 Node.jsの次の例では、誤った結果が得られます。
> 0.1 0.1 > 0.2 0.2 > 0.1 * 0.2 0.020000000000000004 > 0.1 + 0.1 0.010000000000000002
同様に、 Javaの次の例では誤った出力が生成されます。
1 class Main { 2 public static void main(String[] args) { 3 System.out.println("0.1 * 0.2:"); 4 System.out.println(0.1 * 0.2); 5 } 6 }
1 0.1 * 0.2: 2 0.020000000000000004
Python、 Ruby、 Rust、およびその他の言語で同じ計算を実行すると、同じ結果が生成されます。これは、バイナリ浮動小数点数は基数の 10 値を適切に表現していないために発生します。
例、上記の例で使用されている 0.1
は、バイナリでは 0.0001100110011001101
として表されます。ほとんどの場合、これによって重大な問題が発生することはありません。ただし、金融や金融などの精度が重要なアプリケーションでは、データ型として decimal128
を使用します。