Mongo DB の基礎知識

皆さん、こんにちは。LP開発グループのn-ozawanです。
2月6日(金)に冬季オリンピックが始まりますね。開会式は翌日の7日(土)になります。

本題です。
最近、とある事情からMongo DBを勉強しています。今回はMongo DBについて理解できたところをまとめました。

Mongo DB

概要

Mongo DB はドキュメント指向データベースと呼ばれるNoSQLの一種です。ドキュメント指向データベースとは、その名の通り、ドキュメントを保存するデータベースのことです。Mongo DBでは、BSONと呼ばれる、JSONに非常によく似た形式でデータを保存します。

データベースとコレクション

データベースは、Mongo DBで最上位に位置付けられる入れ物です。全てのドキュメントはこのデータベースに保存されます。基本的にデータベースは1つのシステムにつき、1つ作成されます。コレクションは、関連する複数のドキュメントを保存する入れ物です。RDBで言うところのテーブルに該当します。これらの構成を図に表すと以下になります。

この構成は、RDBと比較すると以下のように整理できます。

RDBMongo DB
データベースデータベース
テーブルコレクション
レコード(行)ドキュメント
カラム(列)フィールド

ドキュメント (BSON)

BSONとは、「バイナリ型JSON」の略語です。JSONのデータ構造をバイナリで保存するのが特徴です。MongoDBは内部ではBSONでドキュメントを保存しており、外部(例えばユーザー)とのやり取りではJSON風で入出力するため、JSONを知っていれば違和感なく使うことができます。

先ほど「JSON”風”」と表現しましたが、正確には「Extended JSON(拡張JSON)」であり、厳密にはJSONではありません。BSONはJSONよりもデータ型が増えており、かつ、厳格に扱います。データ型には「整数型」「日付型」から、「バイナリ型」まであります。それら多様なデータ型をテキスト形式で表現するために、従来のJSONを拡張した「Extended JSON」が使われています。

{
  "_id": {"$oid":"5d505646cf6d4fe581014ab2"},                  // ObjectID型
  "createAt": {"$date":"2019-08-11 T 17:54:14.692 Z"},         // 日付型
  "bin": {"$binary": {"base64": "AQIDBA==", "subType": "00"}}, // バイナリ型
  "uuid": {"$uuid":"3b241101-e2bb-4255-8caf-4136c566a962"},    // UUID表現 (厳密にはバイナリ型)
  "int32": {"$numberInt":"10"},                                // 32ビット型Integer、単に{"int32": 10}でもOK
  "int64": {"$numberInt":"50"}                                 // 64ビット型Integer、単に{"int64": 50}でもOK
}

なお、BSONドキュメントの最大サイズは16MBまでとなります。16MBを超えるドキュメントを保存することはできません。

コレクション

コレクションは、関連する複数のドキュメントを保存する入れ物です。Mongo DBはスキーマレスを採用していますので、保存するドキュメントは同じスキーマを持つ必要はありません。ドキュメントのフィールドやデータ型がバラバラでも問題なく保存することができます。

以下は、collコレクションのドキュメントを出力したものです。出力されたドキュメントの内容がそれぞれ異なっていることが分かると思います。

AtlasLocalDev myDeployment [direct: primary] test> db.coll.find()

[
  { _id: ObjectId('6980462972ba91833b8de66a'), name: 'n-ozawan' },
  { _id: ObjectId('6980462972ba91833b8de66b'), title: 'MongoDBの基礎知識' },
  {
    _id: ObjectId('6980465e72ba91833b8de66c'),
    createAt: ISODate('2026-02-02T06:45:24.840Z')
  }
]

とはいえ、中にはスキーマを強制したいケースもあるかと思います。Mongo DBでは、ドキュメントの更新および挿入時に、スキーマを検証する仕組みもあります。以下はstudentsコレクションの作成時に、スキーマ検証ルールを設けています。

db.createCollection("students", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         title: "Student Object Validation",
         required: [ "address", "major", "name", "year" ],
         properties: {
            name: {
               bsonType: "string",
               description: "'name' must be a string and is required"
            },
            year: {
               bsonType: "int",
               minimum: 2017,
               maximum: 3017,
               description: "'year' must be an integer in [ 2017, 3017 ] and is required"
            },
            gpa: {
               bsonType: [ "double" ],
               description: "'gpa' must be a double if the field exists"
            }
         }
      }
   }
} )

上記のスキーマ検証ルールは以下を強制しており、これらに反すると更新および挿入に失敗します。

  • フィールドaddressmajornameyearは必須であること
  • nameは文字列型であること
  • yearは整数型で2017~3017の範囲であること
  • gpaは浮動小数点型であること

おわりに

今回紹介した内容以外にも、Mongo DBにはIndexや結合、集計など、RDBで出来ていたことは一通りできそうです。

ではまた。

Recommendおすすめブログ