はじめに
MongoDBを使用すると、データの構造に柔軟に対応できます。すべてのドキュメントが適合しなければならない特定のスキーマを維持することに縛られることはありません。ドキュメント内の任意のフィールドで、使用可能なデータ型のいずれかを使用できます。 MongoDBでサポートされています。このデフォルトの作業方法にもかかわらず、必要に応じて、MongoDBにJSONスキーマを課して、コレクションに検証を追加することができます。このガイドではスキーマ設計の詳細については説明しませんが、実装するとデータの入力に影響を与える可能性があります。
データ型は、受け入れて保存するデータの一般的なパターンを指定します。データベースを計画するときは、特定のデータ型を別のデータ型よりも選択するタイミングを理解することが最も重要です。選択したタイプによって、データをどのように操作できるか、およびデータがどのように保存されるかが決まります。
JSONとBSON
特定のデータ型の詳細に入る前に、MongoDBがデータを格納する方法を理解することが重要です。 MongoDBおよび他の多くのドキュメントベースのNoSQLデータベースは、JSON(JavaScript Object Notation)を使用してデータレコードをドキュメントとして表します。
JSONを使用してデータを保存することには多くの利点があります。それらのいくつかは:
- 読みやすさ、学習のしやすさ、開発者の間での親しみやすさ
- スパース、階層、または深くネストされているかどうかにかかわらず、フォーマットの柔軟性
- 自己記述型。アプリケーションがJSONデータを簡単に操作できるようにします
- 最小限の数の基本タイプに焦点を当てることができます
JSONは、文字列、数値、ブール値などのすべての基本的なデータ型をサポートします。MongoDBは、実際にはデータレコードをバイナリエンコードされたJSON(BSON)ドキュメントとして保存します。 JSONと同様に、BSONは他のドキュメントや配列へのドキュメントや配列の埋め込みをサポートしています。 BSONでは、JSONでは使用できない追加のデータ型を使用できます。
MongoDBのデータ型は何ですか?
詳細に入る前に、MongoDBでサポートされているデータ型の概要を見てみましょう。
MongoDBは、単純なデータと複雑なデータの両方のさまざまなタイプに適したさまざまなデータタイプをサポートしています。これらには以下が含まれます:
テキスト
String
数値
32-Bit Integer
64-Bit Integer
Double
-
Decimal128
日付/時刻
Date
Timestamp
その他
Object
Array
Binary Data
-
ObjectId
Boolean
Null
Regular Expression
-
JavaScript
Min Key
Max Key
MongoDBでは、各BSONタイプに整数と文字列の両方の識別子があります。このガイドでは、これらの中で最も一般的なものについて詳しく説明します。
文字列タイプ
文字列型は、最も一般的に使用されるMongoDBデータ型です。二重引用符で囲まれた値""
JSONでは文字列値です。テキストとして保存する値は、String
として入力するのが最適です。 。 BSON文字列はUTF-8であり、MongoDBでは次のように表されます。
Type | Number | Alias | ------------------ | ------ | -------- | String | 2 | "string" |
一般に、プログラミング言語のドライバーは、BSONをシリアル化および逆シリアル化するときに、言語の文字列形式からUTF-8に変換します。これにより、BSONは、たとえば国際的な文字を簡単に保存するための魅力的な方法になります。
String
を使用してドキュメントを挿入する データ型は次のようになります:
db.mytestcoll.insertOne({first_name: "Alex"}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d15")}
コレクションをクエリすると、次のようになります。
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d15"), first_name: "Alex"}
$type
の使用 オペレーター
次のデータ型に進む前に、挿入を行う前に値を入力チェックする方法を知っておくことが重要です。前の例を使用して、$type
の使用方法を示します。 MongoDBの演算子。
mytestcoll
を使用してからしばらく経ちました。 以前からのコレクション。 first_name
を使用してコレクションに追加のドキュメントを挿入します 分野。 String
を使用したことを確認するには first_name
の値として保存されたデータ型として 元々、データ型のエイリアス値または数値のいずれかを使用して、以下を実行できます。
db.mytestcoll.find( { "first_name": { $type: "string" } } )
または
db.mytestcoll.find( { "first_name": { $type: 2 } } )
どちらのクエリも、String
を持つすべてのドキュメントの出力を返します first_name
に保存された値 前のセクションの挿入から:
[ { _id: ObjectId("614b37296a124db40ae74d15"), first_name: "Alex" } ]
first_name
に保存されていないタイプをクエリする場合 どのドキュメントのフィールドでも、結果は得られません。これは、それがfirst_name
に格納されている別のデータ型であることを示しています 。
$type
を使用して、一度に複数のデータ型をクエリすることもできます。 次のような演算子:
db.mytestcoll.find( { "first_name": { $type: ["string", "null"] } } )
Null
を挿入しなかったため コレクションに値を入力すると、結果は同じになります:
[ { _id: ObjectId("614b37296a124db40ae74d15"), first_name: "Alex" } ]
これから説明する次のすべてのタイプで同じ方法を使用できます。
数値と数値
MongoDBには、さまざまなシナリオに適したさまざまな数値データ型が含まれています。使用するタイプの決定は、保存する予定の値の性質とデータのユースケースによって異なります。 JSONは、番号が付いているものをすべて番号と呼びます 。これにより、システムはそれを最も近いネイティブデータ型に変換する方法を理解する必要があります。まず、整数と、それらがMongoDBでどのように機能するかを調べます。
整数
Integer
データ型は、小数や小数を含まない整数として数値を格納するために使用されます。整数は正または負の値にすることができます。 MongoDBには、32-Bit Integer
の2つのタイプがあります。 および64-Bit Integer
。これらは、以下の表に示されている2つの方法で表すことができます。number
およびalias
:
Integer type | number | alias | ------------ | ----- | ------------ | `32-bit integer`| 16 | "int" | `64-bit integer`| 18 | "long" |
各タイプの値が収まる範囲は次のとおりです。
Integer type | Applicable signed range | Applicable unsigned range | ------------ | ------------------------------ | ------------------------------- | `32-bit integer`| -2,147,483,648 to 2,147,483,647| 0 to 4,294,967,295 | `64-bit integer`| -9,223,372,036,854,775,808 to | 0 to 18,446,744,073,709,551,615 9,223,372,036,854,775,807
上記のタイプは、有効な範囲によって制限されます。範囲外の値はエラーになります。 Integer
の挿入 MongoDBに入力すると、次のようになります。
db.mytestcoll.insertOne({age: 26}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d14")}
結果を見つけると、次のようになります。
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d14"), age: 26}
名前からわかるように、32-Bit Integer
32ビットの整数精度があり、数字のシーケンスとして保存したくない小さな整数値に役立ちます。数値サイズが大きくなると、64-Bit Integer
に達することができます。 これは64ビットの整数精度を持ち、前者と同じユースケースに適合します。
ダブル
BSONでは、JSONの番号のデフォルトの置換 Double
です データ・タイプ。 Double
データ型は浮動小数点値を格納するために使用され、次のようにMongoDBで表すことができます。
Type | Number | Alias | ------------------ | ------ | -------- | Double | 1 | "double" |
浮動小数点数は10進数を表す別の方法ですが、正確で一貫した精度はありません。
浮動小数点数は、多数の小数で効率的に機能しますが、常に正確であるとは限りません。以下は、Double
を使用してドキュメントを入力する例です。 コレクションに入力します:
db.mytestcoll.insertOne({testScore: 89.6}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d13")}
doubleを使用して計算する場合、予期しない動作につながる可能性のある入力と出力の間にわずかな違いがある可能性があります。正確な値を必要とする操作を実行する場合、MongoDBにはより正確なタイプがあります。
Decimal128
浮動小数点範囲が多い非常に大きな数で作業している場合は、Decimal128
BSONデータ型が最適なオプションになります。これは、正確な金銭的操作を伴うユースケースのように、多くの精度を必要とする値に最も役立つタイプになります。 Decimal128
タイプは次のように表されます:
Type | Number | Alias | ------------------ | ------ | --------- | Decimal128 | 19 | "decimal" |
BSONタイプ、Decimal128
は、小数の丸めが正確に重要な数値を格納するための128ビットの小数表現を提供します。 Decimal128
10進数の34桁の精度、または-6143〜+6144の範囲のsinificandをサポートします。これにより、高い精度が可能になります。
Decimal128
を使用して値を挿入する データ型では、NumberDecimal()
を使用する必要があります あなたの番号をString
として持つコンストラクター MongoDBがデフォルトの数値タイプであるDouble
を使用しないようにするため 。
ここでは、これを示します:
db.mytestcoll.insertOne({price : NumberDecimal("5.099")}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d12")}
コレクションをクエリすると、次のようになります。
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d12"), price: "5.099" }
数値はその精度を維持し、正確な操作を可能にします。 Decimal128
をデモンストレーションする タイプとDouble
、次の演習を行うことができます。
データ型に基づいて精度を失う方法
Double
として10進数の値が多い数値を挿入するとします。 次のようにMongoDBに追加します:
db.mytestcoll.insertOne({ price: 9999999.4999999999 }){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d24")}
このデータをクエリすると、次の結果が得られます。
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d24"), price: 9999999.5}
この値は9999999.5
に切り上げられます 、入力した正確な値を失います。これにより、Double
小数点以下の桁数が多い数値の格納には適していません。
次の例は、Double
を渡すときに精度が失われる場所を示しています Decimal128
を使用して暗黙的に String
の代わりに 前の例のように。
まず、次のDouble
を挿入します 繰り返しますが、NumberDecimal()
を使用します Decimal128
にします タイプ:
db.mytestcoll.insertOne({ price: NumberDecimal( 9999999.4999999999 ) }){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d14")}
注 :MongoDBシェルにこの挿入を行うと、次の警告メッセージが表示されます。
Warning: NumberDecimal: specifying a number as argument is deprecated and may lead to loss of precision, pass a string instead
この警告メッセージは、渡そうとしている番号の精度が低下する可能性があることを示しています。 String
を使用することをお勧めします NumberDecimal()
を使用する 精度を失わないようにします。
警告を無視してドキュメントを挿入すると、値の切り上げによるクエリ結果の精度の低下が見られます。
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d14"), price: Decimal128("9999999.50000000")}
推奨されるNumberDecimal()
に従う場合 String
を使用したアプローチ 精度を維持したまま、次の結果が表示されます。
db.mytestcoll.insertOne({ price: NumberDecimal( "9999999.4999999999" ) } )
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d14"), price: Decimal128("9999999.4999999999")}
正確で正確な値を必要とするユースケースでは、この戻り値が問題を引き起こす可能性があります。金銭的操作を伴う作業は、精度が非常に重要になり、正確な値を持つことが正確な計算に不可欠である例です。このデモンストレーションでは、どの数値データ型がデータに最も適しているかを知ることの重要性を強調しています。
日付
BSONのDate
データ型は、Unixエポック(1970年1月1日)からのミリ秒数を表す64ビット整数です。このデータ型は現在の日付または時刻を格納し、日付オブジェクトまたは文字列として返すことができます。 Date
MongoDBでは次のように表されます:
Type | Number | Alias | ------------------ | ------ | ------------ | Date | 9 | "date" |
注 :BSONDate
タイプは署名されています。負の値は1970年より前の日付を表します。
日付値を返す方法は3つあります。
-
Date()
-文字列を返します -
new Date()
-ISODate()
を使用して日付オブジェクトを返します ラッパー -
ISODate()
-ISODate()
を使用して日付オブジェクトも返します ラッパー
以下にこれらのオプションを示します:
var date1 = Date()var date2 = new Date()var date3 = ISODate()db.mytestcoll.insertOne({firstDate: date1, secondDate: date2, thirdDate: date3}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d22")}
そして戻ってきたとき:
db.mytestcoll.find().pretty(){ "_id" : ObjectId("614b37296a124db40ae74d22"), firstDate: 'Tue Sep 28 2021 11:28:52 GMT+0200 (Central European Summer Time)', secondDate: ISODate("2021-09-28T09:29:01.924Z"), thirdDate: ISODate("2021-09-28T09:29:12.151Z")}
タイムスタンプ
Timestamp
もあります 時間を表すためのMongoDBのデータ型。ただし、Timestamp
内部での使用に最も役立ちますが、ではありません Date
に関連付けられています タイプ。タイプ自体は、イベントが発生した日時を説明するために使用される一連の文字です。 Timestamp
は64ビット値です。ここで:
- 最上位の32ビットは
time_t
です 値(Unixエポックからの秒数) - 最下位32ビットは、増分する
ordinal
です。 特定の秒内の操作の場合
MongoDBでの表現は次のようになります。
Type | Number | Alias | ------------------ | ------ | ------------ | Timestamp | 17 | "timestamp" |
空のタイムスタンプを持つトップレベルのフィールドを含むドキュメントを挿入すると、MongoDBは空のタイムスタンプ値を現在のタイムスタンプ値に置き換えます。これの例外は、_id
の場合です。 フィールドに空のタイムスタンプが含まれています。タイムスタンプ値は常にそのまま挿入され、置き換えられません。
新しいTimestamp
を挿入する MongoDBの値は、new Timestamp()
を使用します 機能し、次のようになります:
db.mytestcoll.insertOne( {ts: new Timestamp() });{ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d23")}
コレクションをクエリすると、次のような結果が返されます。
db.mytestcoll.find().pretty(){ "_id" : ObjectId("614b37296a124db40ae74d24"), "ts" : Timestamp( { t: 1412180887, i: 1 })}
オブジェクト
Object
MongoDBのデータ型は、埋め込みドキュメントの保存に使用されます。埋め込みドキュメントは、key: value
にネストされた一連のドキュメントです。 ペアフォーマット。 Object
のデモを行います 以下に入力してください:
var classGrades = {"Physics": 88, "German": 92, "LitTheoery": 79}db.mytestcoll.insertOne({student_name: "John Smith", report_card: classGrades}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d18")}
その後、新しいドキュメントを表示できます:
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d18"), student_name: 'John Smith', report_card: {Physics: 88, German: 92, LitTheoery: 79}}
Object
データ型は、一緒にアクセスするのに最適なデータを格納するために最適化されます。上記の例の各クラスマークを個別に保存するのではなく、保存、速度、耐久性に関していくつかの効率を提供します。
バイナリデータ
Binary Data
、またはBinData
、データ型は、その名前が示すとおりに機能し、フィールドの値のバイナリデータを格納します。 BinData
ビット配列を効率的に表現できるため、データを保存および検索する場合に最適です。このデータ型は、次の方法で表すことができます。
Type | Number | Alias | ------------------ | ------ | ------------ | Binary data | 5 | "binData" |
Binary Data
を追加する例を次に示します。 コレクション内のドキュメントに:
var data = BinData(1, "111010110111100110100010101")db.mytestcoll.insertOne({binaryData: data}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d20")}
結果のドキュメントを表示するには:
db.mytestcoll.find().pretty(){ "_id" : ObjectId("614b37296a124db40ae74d20"), "binaryData" : BinData(1, "111010110111100110100010101")}
ObjectId
ObjectId
タイプはMongoDBに固有であり、ドキュメントの一意のIDを格納します。 MongoDBは_id
を提供します すべてのドキュメントのフィールド。 ObjectIdのサイズは12バイトで、次のように表すことができます。
Type | Number | Alias | ------------------ | ------ | ------------ | ObjectId | 7 | "objectId" |
ObjectIdは、12バイトの構成を構成する3つの部分で構成されています。
- 4バイトのタイムスタンプ値 、Unixエポックからの秒数で測定されたObjectIdの作成を表します
- 5バイトのランダム値
- 3バイトのインクリメントカウンター ランダムな値に初期化されます
MongoDBでは、コレクション内の各ドキュメントに一意の_id
が必要です 主キーとして機能します。 _id
の場合 挿入されたドキュメントのフィールドは空のままになります。MongoDBはフィールドのObjectIdを自動的に生成します。
_id
にObjectIdsを使用することにはいくつかの利点があります :
-
mongosh
で (MongoDBシェル)、ObjectId
の作成時間ObjectId.getTimestamp()
を使用してアクセスできます メソッド。 -
_id
での並べ替えObjectId
を格納するフィールド データ型は、作成時間による並べ替えとほぼ同じです。
これまでの例でObjectIdを確認してきましたが、次のようになります。
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d19")}
注 :ObjectId値は時間の経過とともに増加するはずですが、必ずしも単調であるとは限りません。これは、次の理由によるものです:
- 時間分解能は1秒しかないため、同じ秒内に作成された値は順序が保証されません。
- 値はクライアントによって生成されます。クライアントはシステムクロックが異なる場合があります
ブール値
MongoDBにはネイティブのBoolean
があります コレクション内にtrue値とfalse値を格納するためのデータ型。 Boolean
MongoDBでは、次のように表すことができます。
Type | Number | Alias | ------------------ | ------ | ------------ | Boolean | 8 | "bool" |
Boolean
を使用してドキュメントを挿入する データ型は次のようになります:
db.mytestcoll.insertOne({isCorrect: true, isIncorrect: false}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d21")}
次に、ドキュメントを検索すると、結果は次のように表示されます。
db.mytestcoll.find().pretty(){ "_id" : ObjectId("614b37296a124db40ae74d21") "isCorrect" : true, "isIncorrect" : false}
正規表現
Regular Expression
MongoDBのデータ型では、フィールドの値として正規表現を格納できます。 MongoDBは、正規表現言語としてPCRE(Perl互換正規表現)を使用しています。
次のように表すことができます:
Type | Number | Alias | ------------------ | ------ | ------- | Regular Expression | 11 | "regex" |
BSONを使用すると、正規表現やデータベースを操作するときに一般的に発生する一般的な「文字列からの変換」手順を回避できます。このタイプは、検証パターンまたは一致するトリガーを必要とするデータベースオブジェクトを作成する場合に最も役立ちます。
たとえば、Regular Expression
を挿入できます。 次のようなデータ型:
db.mytestcoll.insertOne({exampleregex: /tt/}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d16")}db.mytestcoll.insertOne({exampleregext:/t+/}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d17")}
この一連のステートメントにより、これらのドキュメントがコレクションに追加されます。その後、コレクションをクエリして、挿入されたドキュメントを見つけることができます。
db.mytestcoll.find().pretty(){ _id: ObjectId("614b37296a124db40ae74d16"), exampleregex: /tt/, _id: ObjectId("614b37296a124db40ae74d17"), exampleregex: /t+/ }
正規表現パターンは、文字列ではなく正規表現として保存されます。これにより、特定の文字列をクエリして、目的の文字列に一致する正規表現を持つ返されたドキュメントを取得できます。
JavaScript(スコープなし)
前述のRegular Expression
とよく似ています データ型であるBSONを使用すると、MongoDBはスコープなしでJavaScript関数を独自の型として格納できます。 JavaScript
タイプは次のように認識できます:
Type | Number | Alias | ------------------ | ------ | ------------ | JavaScript | 13 | "javascript" |
JavaScript
を使用してコレクションにドキュメントを追加する データ型は次のようになります:
db.mytestcoll.insertOne({jsCode: "function(){var x; x=1}"}){ "acknowledged": true, "insertedId": ObjectId("614b37296a124db40ae74d122")}
この機能を使用すると、特定のユースケースで必要な場合に、JavaScript関数をMongoDBコレクション内に保存できます。
注 :MongoDBバージョン4.4以降では、代替JavaScriptタイプであるJavaScript with Scope
データ型、非推奨になりました
結論
この記事では、MongoDBデータベースを操作するときに役立つ一般的なデータ型のほとんどについて説明しました。このガイドで明示的にカバーされていない追加のタイプがあり、ユースケースによっては役立つ場合があります。これらのタイプを理解することから始めると、ほとんどのユースケースがカバーされます。 MongoDBデータベースのモデリングを開始するための強力な基盤です。
有効な値を使用し、期待される結果でデータを操作できるように、データベースを使用するときに使用できるデータ型を知ることが重要です。 Double
に示されているように、データを適切に入力しないと発生する可能性のあるリスクがあります。 対Decimal128
エクササイズ。特定のタイプにコミットする前に、これについて考えることが重要です。
MongoDBデータベースでPrismaをチェックアウトすることに興味がある場合は、データコネクタのドキュメントをチェックアウトできます。