MongoDBのデータ型についてまとめます。一般的なプログラミング言語と同じように、MongoDBもint型やString型のようなデータ型の概念があります。例えば、「123」と「”123″」では意味が異なり、前者はint型で後者はString型です。
前提
公式ドキュメント
参考となる公式ドキュメントを以下に示します。
BSON Types
https://www.mongodb.com/docs/manual/reference/bson-types/
Data Types
https://www.mongodb.com/docs/mongodb-shell/reference/data-types/
$type
https://www.mongodb.com/docs/manual/reference/operator/query/type/
動作確認済環境
- Rocky Linux 8.6
- MongoDB Server 6.0.2
データ型の動作確認
データ型の体験
まずはデータ型を体験してみましょう。以下のテスト用データを登録します。
db.addressBook.insertMany( [ { "_id" : 1, address : "2030 Martian Way", zipCode : "90698345" }, { "_id" : 2, address: "156 Lunar Place", zipCode : 43339374 }, { "_id" : 3, address : "2324 Pluto Place", zipCode: NumberLong(3921412) }, { "_id" : 4, address : "55 Saturn Ring" , zipCode : NumberInt(88602117) }, { "_id" : 5, address : "104 Venus Drive", zipCode : ["834847278", "1893289032"]} ] )
前述のテスト用データを検索してみましょう。_id:1として登録されている郵便番号「90698345」の検索を試みる以下2種類のクエリを実行してみます。
db.addressBook.find({zipCode: 90698345}) db.addressBook.find({zipCode: "90698345"})
実行結果は以下のようになります。前者は「Double型の90698345」に合致するレコードが存在するかを調べるクエリなので、検索結果は0件です。後者は「String型の90698345」に合致するレコードが存在するかを調べるクエリなので、検索結果は0件です。
test> db.addressBook.find({zipCode: 90698345}) test> db.addressBook.find({zipCode: "90698345"}) [ { _id: 1, address: '2030 Martian Way', zipCode: '90698345' } ] test>
データ型の調査
MongDBには以下のデータ型が存在します。
Type | Number | Alias | Notes |
---|---|---|---|
Double | 1 | “double” | |
String | 2 | “string” | |
Object | 3 | “object” | |
Array | 4 | “array” | |
Binary data | 5 | “binData” | |
Undefined | 6 | “undefined” | Deprecated. |
ObjectId | 7 | “objectId” | |
Boolean | 8 | “bool” | |
Date | 9 | “date” | |
Null | 10 | “null” | |
Regular Expression | 11 | “regex” | |
DBPointer | 12 | “dbPointer” | Deprecated. |
JavaScript | 13 | “javascript” | |
Symbol | 14 | “symbol” | Deprecated. |
JavaScript code with scope | 15 | “javascriptWithScope” | Deprecated in MongoDB 4.4. |
32-bit integer | 16 | “int” | |
Timestamp | 17 | “timestamp” | |
64-bit integer | 18 | “long” | |
Decimal128 | 19 | “decimal” | |
Min key | -1 | “minKey” | |
Max key | 127 | “maxKey” |
型を調査するには$type演算子を使用します。演算子の後ろには上記のNumberまたはAliasを指定します。
例えば、zipCodeフィールドがString型であるレコードを取得するには以下のように指定します。
test> db.addressBook.find( { "zipCode" : { $type : 2 } } ); [ { _id: 1, address: '2030 Martian Way', zipCode: '90698345' }, { _id: 5, address: '104 Venus Drive', zipCode: [ '834847278', '1893289032' ] } ] test> db.addressBook.find( { "zipCode" : { $type : "string" } } ); [ { _id: 1, address: '2030 Martian Way', zipCode: '90698345' }, { _id: 5, address: '104 Venus Drive', zipCode: [ '834847278', '1893289032' ] } ] test>
例えば、zipCodeフィールドが32-bit integer型であるレコードを取得するには以下のように指定します。
[coe] test> db.addressBook.find( { “zipCode” : { $type : 16 } } );[
{ _id: 2, address: ‘156 Lunar Place’, zipCode: 43339374 },
{ _id: 4, address: ’55 Saturn Ring’, zipCode: 88602117 }
] test> db.addressBook.find( { “zipCode” : { $type : “int” } } );
[
{ _id: 2, address: ‘156 Lunar Place’, zipCode: 43339374 },
{ _id: 4, address: ’55 Saturn Ring’, zipCode: 88602117 }
] test>
[/code]
また、MongoDB CompassのようなGUIツールの中には、グラフィカルに型を表示するものもあります。
データ型の指定
本シナリオが使用するテストデータを再掲します。例えば、NumberLong()やNumberInt()のようにデータ型を明示指定しているものもあれば、”90698345″や43339374のように暗黙的な型指定に頼った操作方法もあります。
db.addressBook.insertMany( [ { "_id" : 1, address : "2030 Martian Way", zipCode : "90698345" }, { "_id" : 2, address: "156 Lunar Place", zipCode : 43339374 }, { "_id" : 3, address : "2324 Pluto Place", zipCode: NumberLong(3921412) }, { "_id" : 4, address : "55 Saturn Ring" , zipCode : NumberInt(88602117) }, { "_id" : 5, address : "104 Venus Drive", zipCode : ["834847278", "1893289032"]} ] )
暗黙の型指定
型を指定せずに数値を使用した場合は、数値の大きさによりint型になったりDouble型になったりします。以下にテストデータを示します。
db.dataTypeTest.insertMany( [ { _id: 1, value: 1, expectedType: 'Int32' }, { _id: 2, value: Long("1"), expectedType: 'Long' }, { _id: 3, value: 1.01, expectedType: 'Double' }, { _id: 4, value: Decimal128("1.01"), expectedType: 'Decimal128' }, { _id: 5, value: 3200000001, expectedType: 'Double' } ] )
32bitで表せる数字「1」はint型として扱われます。
test> db.dataTypeTest.find({value : { $type : 'int' }}) [ { _id: 1, value: 1, expectedType: 'Int32' } ] test>
32bitを超過する数字「3200000001」や少数で表せる「1.01」はdouble型として扱われます。
test> db.dataTypeTest.find({value : { $type : 'double' }}) [ { _id: 3, value: 1.01, expectedType: 'Double' }, { _id: 5, value: 3200000001, expectedType: 'Double' } ] test>