---
title: "MongoDBは使ってはいけない？向かない業務の判断基準とドキュメント構造・使い方入門"
url: "https://www.issoh.co.jp/column/details/3006/"
published: 2024-07-10
updated: 2026-10-10
categories: ["データベース"]
publisher: "株式会社一創"
---

# MongoDBは使ってはいけない？向かない業務の判断基準とドキュメント構造・使い方入門

MongoDBは、データを表の行ではなく「ドキュメント」という単位で保存するドキュメント指向のNoSQLデータベースです。「MongoDBは使ってはいけない」という声の多くは、データが消える、勝手に外部へ公開される、といった初期の評判か、RDBで組むべき業務にMongoDBを当てた失敗談から来ています。前者は現行の既定値でかなり解消されており、後者は今も変わらない適性の問題です。この記事では、ドキュメントの構造とmongoshでの基本操作を押さえたうえで、評判の出どころを公式ドキュメントの現行仕様と突き合わせ、使ってはいけない業務と使うべき条件を判定表とコード例で整理します。MongoDB互換のAPIをAWS上のマネージドサービスで使う選択肢は、[Amazon DocumentDBとは何かを解説した記事](https://www.issoh.co.jp/tech/details/15445/)で扱っています。

## まとめ：MongoDBを使ってはいけない場面と使うべき条件、ドキュメントの要点

- **使ってはいけないのは**、会計・在庫引当・決済のように複数のデータを厳密な整合性で同時に更新する業務と、正規化された多対多の結合や帳票集計が中心の基幹システム。ここはRDBを選ぶ。
- **使うべきなのは**、1件がまとまりを持ち項目が一定でないデータ（商品カタログ、投稿、IoTログ、設定・プロフィール）を大量に扱い、将来の水平スケールが見込める場合。
- 「データが消える」「流出する」という評判は古い既定値に由来する部分が大きい。現行は書き込み確認（write concern）の既定が**majority**、待受は**localhostのみ**が既定。ただし外部公開や旧版の放置は今も事故になる。
- データの基本単位はドキュメントで、内部表現は**BSON**。1件の上限は**16MiB**、超えるデータは**GridFS**で分割する。
- 「スキーマレス＝設計不要」は誤り。`$jsonSchema`によるスキーマバリデーションで型と必須項目を強制する。
- ライセンスは**SSPL**で、OSIの承認を受けていない。自社アプリのDBとしては無料で使えるが、MongoDBそのものをサービスとして外部提供する場合に条件が付く。
- 2026年10月時点の現行安定版は**9.0系**（2026年9月リリース）。新規構築は9.0系か8.0系、7.0系は2027年8月末でサポートが終わる。

以下、ドキュメントの中身から順に、具体例とコマンドで解説します。採用判断だけを急ぐ場合は「使ってはいけないケース」の章から読んでも構いません。

## MongoDBとは：ドキュメント指向NoSQLの位置づけとリレーショナルDBとの対応

MongoDBは2009年に公開されたNoSQLデータベースで、開発元はMongoDB, Inc.（旧10gen）です。リレーショナルデータベース（RDB）が行と列の表でデータを持つのに対し、MongoDBは1件のデータを1つのドキュメントとして保存します。ドキュメントは階層構造をそのまま表現できるため、注文とその明細、ユーザーとそのプロフィールのような「1つのまとまり」を、複数テーブルに分けずに1件で保持できる構造です。RDBとNoSQLの全体像やDBMSの種類から選び方を確かめたい場合は、[データベースの種類とRDB・NoSQLの選び方を解説した記事](https://www.issoh.co.jp/tech/details/13012/)が前提知識になります。

### リレーショナルデータベースとの用語対応と事前にスキーマを宣言しない違い

RDBの経験があれば、用語を対応付けると理解が速くなります。構造の呼び方はほぼ1対1で対応します。

| リレーショナルDB | MongoDB      | 役割         |
| --------- | ------------ | ---------- |
| データベース    | データベース       | コレクションの入れ物 |
| テーブル      | コレクション       | ドキュメントの集合  |
| 行（レコード）   | ドキュメント       | データの1件     |
| 列（カラム）    | フィールド        | キーと値の対     |
| 主キー       | \_idフィールド    | 一意な識別子     |
| JOIN      | 埋め込み／$lookup | データの関連付け   |

決定的な違いは、テーブルが全行で同じ列を持つのに対し、コレクション内のドキュメントは**フィールド構成がドキュメントごとに違ってよい**点です。列を追加するときのようなスキーマ変更（マイグレーション）を伴わずに、新しいフィールドを持つドキュメントを書き込めます。仕様変更が多い初期開発と相性が良い一方、後述のとおり構造の乱れを招く原因にもなります。

### NoSQL4分類の中でドキュメント型が値の中身で検索できる理由と互換サービス

NoSQLはキーバリュー型（Redisなど）、カラム指向型（Cassandraなど）、グラフ型（Neo4jなど）、ドキュメント型に大別されます。キーバリュー型が「値」を単なる塊として扱うのに対し、ドキュメント型は値の内部構造（フィールドや配列）をデータベース側が理解し、その中身を対象に検索・インデックス・集計が可能です。MongoDBはこのドキュメント型の代表的な実装で、MongoDB互換のAPIを提供するAmazon DocumentDBやAzure Cosmos DB for MongoDBなどの互換サービスもあります。互換サービスは対応する演算子や版がMongoDB本体と一致しないことがあるため、移行時は互換表の確認が要ります。

## MongoDBのドキュメント構造：BSON・\_id・埋め込みと16MiB上限の基本

MongoDBを理解する中心は「ドキュメント」です。ドキュメントは、キー（フィールド名）と値の対を集めたもので、見た目はJSONそのものです。実データはBSON（Binary JSON）というバイナリ形式で保存され、JSONにはない日時・バイナリ・64bit整数などの型を扱えます。

### ドキュメントの構造と主キーになる\_idフィールド・12バイトのObjectId

次はユーザー1件を表すドキュメントの例です。文字列・数値・配列・入れ子（埋め込みドキュメント）が1件の中に同居しています。

```
{
  "_id": ObjectId("665f1a2b3c4d5e6f7a8b9c0d"),
  "name": "田中太郎",
  "age": 34,
  "tags": ["mongodb", "nosql"],
  "address": {
    "city": "東京",
    "zip": "100-0001"
  }
}
```

すべてのドキュメントは**\_id**という一意なフィールドを必ず持ち、これが主キーの役割を果たします。挿入時に指定しなければ、MongoDBが**ObjectId**という12バイトの値を自動生成する仕組みです。ObjectIdは先頭に生成時刻を含むため、\_idの順で並べるとおおむね作成順に並ぶ性質があります。整数の連番や既存の一意なキー（メールアドレスなど）を\_idに使うこともできます。

### 埋め込みドキュメントと参照を更新頻度と読み取り単位で使い分ける基準

上の例の`address`のように、ドキュメントの中に別のドキュメントを入れられます。これを埋め込み（ネスト）と呼びます。`tags`のように値を配列で持つこともでき、配列の要素にドキュメントを並べることも可能です。RDBなら別テーブルに分けてJOINする関連データを、アクセス単位がまとまっているなら1ドキュメントに埋め込むのがMongoDBの基本設計です。1回の読み取りで関連データがそろうため、JOINを避けられます。

逆に、同じデータを多数のドキュメントに埋め込むと更新箇所が増えます。判断の目安は2つです。一緒に読む頻度が高く、親と同時にしか更新しないなら埋め込む。単独で更新される、または多数の親から共有されるなら参照（別コレクションの\_idを持つ）にする。この判断は[公式マニュアルのData Modeling](https://www.mongodb.com/docs/manual/data-modeling/)でも、アプリの読み書きパターンから決めるよう説明されています。

### 1ドキュメント16MiBの上限とネスト100階層の制限、超える場合のGridFS

[公式のLimits and Thresholds](https://www.mongodb.com/docs/manual/reference/limits/)によると、1つのBSONドキュメントの最大サイズは**16メビバイト（16MiB）**で、入れ子の深さは**100階層**までです。1件が過大なメモリや転送帯域を消費しないための制限で、配列に要素を無制限に追加し続ける設計（際限なく伸びる配列）は上限に達するリスクがあります。動画や大きなファイルなど16MiBを超えるデータは、ドキュメントに直接入れず**GridFS**という仕組みでチャンクに分割して保存します。設計時は「1ドキュメントが将来どこまで大きくなるか」を先に見積もってください。コメントやログのように件数が増え続けるものは、親に埋め込まず別コレクションへ分けるのが定石です。

### BSONとJSONの型の違いとDecimal128・Date型を選ぶ金額と日時の扱い

JSONは文字列・数値・真偽値・配列・オブジェクト・nullしか表せませんが、BSONはこれに加えて`Date`（日時）、`ObjectId`、`Decimal128`（誤差のない10進数、金額計算向き）、バイナリ、正規表現などの型を持ちます。金額を浮動小数点で持つと誤差が出るため`Decimal128`を使う、日時は文字列でなく`Date`型で持って範囲検索やソートを効かせる、といった型の使い分けが、後の検索性能と正確さに効いてきます。

## 「MongoDBは使ってはいけない」と言われる理由：古い評判と現行仕様の差

「使ってはいけない」という評価には、今は既定値で解消された問題と、今も運用次第で起きる問題が混ざっています。区別せずに受け取ると、使える場面で避けたり、危ない運用をそのまま続けたりする原因になります。ここで確認するのは、4つに分けた評判の出どころと、現行の公式ドキュメントとの対応です。

### 書き込み消失の評判とwrite concernの既定値majorityの現状

MongoDBの初期のドライバには、書き込み結果の確認を待たずに処理を返す設定が既定だった時期がありました。障害時に「書いたはずのデータが無い」という報告が相次ぎ、「データが消えるDB」という評判の元になっています。

現行の既定値は、当時と異なる設定です。[公式マニュアルのWrite Concern](https://www.mongodb.com/docs/manual/reference/write-concern/)では、レプリカセットとシャードクラスタの既定の書き込み保証は`majority`（投票権を持つメンバーの過半数がoplogへ永続化したら確認を返す）と明記されています。稼働中の設定は次のコマンドで確かめられます。

```
db.adminCommand({ getDefaultRWConcern: 1 })
```

注意点は、アプリ側で`w: 1`や`w: 0`を明示すると速さと引き換えに保証が弱まることです。古いサンプルコードを写したまま、この指定が残っていないかを確認してください。単一ノードの構成では、そもそも複製先が無いためサーバ障害に弱い点も変わりません。

### 認証なし公開による流出事故とlocalhostバインド既定・待受ポートの遮断

2017年前後には、認証を設定しないままインターネットへ公開されたMongoDBが大量にデータを消され、身代金を要求される事件が報じられました。これも「使ってはいけない」の大きな出どころです。

現在の既定は、[公式のIP Binding](https://www.mongodb.com/docs/manual/core/security-mongodb-configuration/)のページにあるとおり、mongodとmongosは**localhostにだけバインド**します（3.6系で変更）。外部から届くのは、利用者が`bindIp`を広げたときです。広げる場合は、認証を必ず有効にし、待受ポート（既定は27017番）をファイアウォールで信頼できるネットワークに絞ります。

```
# /etc/mongod.conf（抜粋）
net:
  port: 27017
  bindIp: 127.0.0.1,10.0.1.15
security:
  authorization: enabled
```

`bindIp`に`0.0.0.0`を書くと全インターフェースで待ち受けます。検証環境で一時的に書いた設定を本番に持ち込むのが、典型的な事故の経路です。

### MongoBleedなど脆弱性を放置した旧版運用が招く認証前の情報漏えい

2025年12月には、zlib圧縮メッセージの処理の欠陥で、認証前のクライアントにサーバのメモリ内容が漏れる脆弱性CVE-2025-14847（通称MongoBleed）が公表されました。[NVDのCVE-2025-14847](https://nvd.nist.gov/vuln/detail/CVE-2025-14847)では3.6系から8.2系までの幅広い版が影響を受けるとされ、修正版の無い旧系列も含まれます。影響版と修正版、確認コマンドは[MongoBleed（CVE-2025-14847）の影響バージョンと対策を解説した記事](https://www.issoh.co.jp/tech/details/10540/)で詳しく扱っています。

ここから言えるのは、MongoDBが特別に危ないということではありません。サポートが切れた版を外部到達可能なまま動かす運用が危ない、ということです。自己管理で運用するなら、パッチ適用の担当と頻度を決めてから採用してください。それができない体制なら、パッチをベンダー側で当てるMongoDB Atlasのようなマネージドサービスの方が向いています。

### SSPLライセンスがSaaS提供で問題になる条件とOSI非承認の意味

MongoDB Community Editionは無料で使えますが、[公式のSSPL FAQ](https://www.mongodb.com/legal/licensing/server-side-public-license/faq)によると、2018年10月16日以降にリリースされた版とパッチは**SSPL（Server Side Public License）**の対象です。SSPLはGPL v3を土台にしていますが、FAQ自身が「OSIの承認を受けていない」と書いており、OSIが承認する意味での「オープンソース」には当たりません。GPLとの実質的な違いは第13条で、MongoDBを一般向けのサービスとして提供する企業に、そのサービスの提供に使うソフトウェアのソースコード公開を求めます。

自社アプリのデータベースとして使う分には、この条件は問題になりません。問題になるのは「MongoDBそのものを、利用者が直接操作できるデータベースサービスとして外部提供する」用途で、この場合はライセンス条項の精査か、MongoDB Atlasや商用版の利用を検討します。`mongodb oss`と検索して「無料＝オープンソース」と理解してしまうのが、よくある取り違えです。

## MongoDBを使ってはいけないケース：RDBを選ぶべき業務と要件の判断基準

前の章の問題は運用で避けられます。この章で扱うのは、運用では埋まらない適性の問題です。次の条件に当てはまるなら、MongoDBを選ばない方が安全です。

| 要件・条件            | MongoDB  | RDB      |
| ---------------- | -------- | -------- |
| 複数データの厳密な同時更新が常用 | 使ってはいけない | 向く       |
| 多対多の結合と帳票集計が中心   | 使ってはいけない | 向く       |
| 表に収まる小規模データ      | 強みが効かない  | 十分       |
| 項目が一定でない大量データ    | 向く       | 列追加が重い   |
| 書き込み量の水平スケール     | 向く       | 構成が難しい   |
| 1件を丸ごと読み書きする処理   | 向く       | JOINが増える |

上の3行のどれかが業務の中心にあるなら、RDBを第一候補にします。下の3行が中心で、上の3行が一部にとどまるなら、MongoDBを検討する価値があります。

### 会計・在庫引当・決済など複数ドキュメントの厳密な同時更新が中心の業務

会計・在庫引当・決済のように、複数のデータを厳密な整合性で同時更新する業務は、リレーショナルデータベースの方が素直です。MongoDBは4.0系でレプリカセットのマルチドキュメントACIDトランザクションに対応し、4.2系でシャード横断にも対応しました。それでも[公式マニュアルのTransactions](https://www.mongodb.com/docs/manual/core/transactions/)は、分散トランザクションは単一ドキュメントの書き込みより性能コストが大きく、適切なスキーマ設計の代わりにはならない、と明記しています。

運用上の制約もあります。[本番運用の考慮事項（Production Considerations）](https://www.mongodb.com/docs/manual/core/transactions-production-consideration/)によると、トランザクションは既定で1分未満に終える必要があり、超えたものは自動で中断されます。設計がトランザクション多用に向かっている時点で、それはRDBを選ぶべきサインです。ACIDや分離レベルの違いを押さえ直すなら、[トランザクションの分離レベルとACIDを解説した記事](https://www.issoh.co.jp/tech/details/13690/)が役に立ちます。

### 正規化された多対多の結合と帳票集計が業務の中心になる基幹システム

受注・出荷・請求・顧客・商品が多対多で結びつき、それらを横断した帳票や月次集計が業務の中心なら、正規化したテーブルとSQLのJOINで組む方が保守しやすくなります。MongoDBにも`$lookup`による結合はありますが、結合を前提にデータを分けた時点でドキュメントモデルの利点は薄れるのが難点です。どこまで正規化し、どこで非正規化するかの判断は[データベース正規化と非正規化の判断を解説した記事](https://www.issoh.co.jp/tech/details/16281/)で整理しています。結合と集計の比重が高い基幹システムでは、MongoDBを無理に選ばないのが安全です。

### スキーマ無設計で書き込み続けたコレクションが集計と移行で破綻する失敗

「スキーマレスだから設計不要」は誤解です。スキーマの強制がないだけで、データモデルの設計は依然として必要です。`price`が数値のドキュメントと文字列のドキュメントが混ざる、`userId`と`user_id`が併存する、といった状態になると、アプリ側の条件分岐が増え、集計結果が静かに狂います。無設計で書き込み続けたコレクションは、後からの整形コストが非常に高くつきます。

防ぐ手段は、後述する`$jsonSchema`のスキーマバリデーションをコレクション作成時に設定しておくことです。「型と必須項目は決める、それ以外の項目の追加は許す」という運用にすれば、柔軟さを残したまま乱れを止められます。

### MySQLやPostgreSQLで足りる小規模・強整合でスケールアウト不要の要件

データ量が小さく、スケールアウトの必要がなく、表形式にきれいに収まる業務データなら、MySQLやPostgreSQLで十分です。水平スケールやスキーマ柔軟性という強みが効かない要件では、運用ノウハウが蓄積されたRDBを選ぶ方が、レプリカセットやシャーディングの構築・運用コストを負わずに済みます。MySQLの特徴と版の選び方は[MySQLのバージョン選定と採用判断を解説した記事](https://www.issoh.co.jp/tech/details/13135/)にまとめています。「新しいから」ではなく「その要件で強みが効くか」で選ぶのが判断基準です。

既存システムがMongoDBで組まれていて上の条件に当てはまる、あるいは新規開発でRDBとMongoDBのどちらにするか決めきれない場合は、データモデルと移行計画を一緒に設計するのが近道です。一創の[データベース設計・移行支援](https://www.issoh.co.jp/service/system/database/)では、要件からのDB選定、スキーマ設計、RDBとNoSQLの間の移行までを支援しています。

## MongoDBを使うべき条件とメリット：可変スキーマと水平スケールが効く用途

MongoDBの利点は、単なる「柔軟」という抽象語ではなく、具体的な作業がどう楽になるかで捉えると判断しやすくなります。

### 開発速度とシャーディングによる水平分割、JOIN不要の読み取りが効く場面

最も効くのは開発速度への効果です。スキーマを事前に固定しないため、フィールドの追加が既存データへのマイグレーションなしで済み、仕様が動く初期開発や、ドキュメントごとに項目が異なるデータで開発が止まりません。次に効くのが規模への強さで、シャーディングによってデータを複数サーバーへ水平分割でき、書き込み・データ量の増加にサーバー追加で対応できます。シャードキーの選び方で性能が大きく変わる点は、[シャーディングの仕組みとシャードキー設計を解説した記事](https://www.issoh.co.jp/tech/details/16274/)で詳しく扱っています。加えて、アクセス単位を1ドキュメントに埋め込めばJOINなしで関連データを一括取得できるため、読み取りが素直になる構造です。

向いているのは、構造が可変で件数が多いデータです。具体的には、ユーザー生成コンテンツ（投稿・コメント）、カテゴリごとに属性が違う商品カタログや在庫、IoT・センサーのログ、アプリの設定・プロフィールなど、「1件がまとまりを持ち、項目が一定でない」ケースです。

### MongoDBを選ぶ前にPostgreSQLのJSONB列で足りるかを確かめる判断

「一部の項目だけが可変」という要件なら、MongoDBを新たに導入せず、PostgreSQLのJSONB列で受ける選択肢があります。基幹データは正規化したテーブルに置き、可変な属性だけをJSONB列に入れてGINインデックスを張る構成です。運用するDBが1種類で済み、トランザクションとJOINもそのまま使えます。

MongoDBを選ぶ理由が残るのは、データの大半がドキュメント形式で、書き込み量の水平スケールが見込める場合です。JSONB列で受ける場合の格納方式と索引の設計境界は、[PostgreSQL JSONBの使い方と正規化列との設計境界を解説した記事](https://www.issoh.co.jp/tech/details/16990/)で比較しています。

## MongoDBの基本操作：mongoshで接続・CRUD・集計・検証を試す手順

MongoDBの操作は、公式シェルの`mongosh`か、Node.js・Pythonなど各言語のドライバから行います。ここではmongoshで、接続から作成・読み取り・更新・削除（CRUD）、集計、インデックス、スキーマ検証、トランザクションまでの最小の流れを示します。

### mongoshでローカルのMongoDBに接続しデータベースを選ぶ最初の2行

mongoshで接続し、使うデータベースを`use`で選びます。存在しないデータベースやコレクションは、最初のドキュメントを書き込んだ時点で自動的に作られます。事前定義は不要です。

```
mongosh "mongodb://localhost:27017"
use shop
```

### insertOne・find・updateOne・deleteOneによるCRUD操作

ドキュメントのCRUD操作では、コレクション（下では`users`）に対してメソッドを呼ぶのが基本形です。検索条件や更新内容も、すべてドキュメント（オブジェクト）で渡します。

```
db.users.insertOne({ name: "田中太郎", age: 34 })
db.users.find({ age: { $gte: 30 } })
db.users.updateOne(
  { name: "田中太郎" },
  { $set: { age: 35 } }
)
db.users.deleteOne({ name: "田中太郎" })
```

検索の`$gte`は「以上」を表す比較演算子で、ほかに`$lt`（未満）や`$in`（いずれかに一致）などがあります。更新は`$set`で指定フィールドだけを書き換え、ドキュメント全体を置き換えないのが安全な使い方です。複数件をまとめて扱う`insertMany`や`updateMany`も同じ形で使えます。

### 集計を担うアグリゲーションパイプラインの$matchと$groupの書き方

合計・平均・グループ集計は`aggregate`にステージの配列を渡すパイプラインで行います。データが`$match`（絞り込み）→`$group`（集計）と順に流れていくイメージです。

```
db.orders.aggregate([
  { $match: { status: "paid" } },
  { $group: { _id: "$userId", total: { $sum: "$amount" } } }
])
```

この例は、支払い済みの注文をユーザーごとに合計します。RDBのGROUP BYに相当しますが、ステージを積み重ねて整形・結合（`$lookup`）まで一本のパイプラインで書けるのが特徴です。

### createIndexで検索を高速化するインデックス設計と一意制約・ESR原則

検索対象のフィールドにインデックスがないと、MongoDBはコレクション全体を走査するため、件数が増えるほど遅くなります。`createIndex`でインデックスを張ると、そのフィールドの検索・ソートが高速になります。`unique`を付ければ一意制約としても設定可能です。

```
db.users.createIndex({ email: 1 }, { unique: true })
```

複合インデックスの並び順（等価→ソート→範囲の「ESR」原則）や種類の使い分けは、[MongoDBのインデックスの種類とそれぞれの特徴](https://www.issoh.co.jp/tech/details/2626/)で詳しく扱っています。パフォーマンスチューニングの中心はインデックス設計です。

### $jsonSchemaのスキーマバリデーションで型と必須フィールドを強制する設定

「使ってはいけないケース」で触れた構造の乱れは、コレクション作成時の検証ルールで止めます。[公式マニュアルのSchema Validation](https://www.mongodb.com/docs/manual/core/schema-validation/)にあるとおり、許可する型や値の範囲はフィールドごとに指定可能です。次の例は、注文に`userId`・`amount`・`createdAt`を必須とし、金額を`Decimal128`、日時を`Date`型に限定します。

```
db.createCollection("orders", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["userId", "amount", "createdAt"],
      properties: {
        userId: { bsonType: "objectId" },
        amount: { bsonType: "decimal" },
        createdAt: { bsonType: "date" },
        status: { enum: ["pending", "paid", "canceled"] }
      }
    }
  },
  validationLevel: "strict",
  validationAction: "error"
})

// 型が違う書き込みは拒否される（Document failed validation）
db.orders.insertOne({ userId: ObjectId(), amount: "1200", createdAt: new Date() })
```

`properties`に書いていないフィールドは、既定では自由に追加できます。既存のコレクションには`collMod`コマンドで後から検証ルールを付けられ、`validationAction: "warn"`にすれば拒否せずログへ記録するだけにとどめられます。既存データを壊さずに導入するなら、まずwarnで違反件数を把握してからerrorへ切り替える手順が安全です。

### 単一ドキュメントの原子更新とマルチドキュメントトランザクションの書き方

MongoDBでは、1つのドキュメントへの更新は常に原子的です。在庫の引き当てなら、条件付きの更新1回で「在庫が1以上のときだけ1減らす」を安全に書けます。

```
// 在庫が1以上のときだけ1減らす（単一ドキュメントなのでトランザクション不要）
db.inventory.updateOne(
  { sku: "A-100", qty: { $gte: 1 } },
  { $inc: { qty: -1 } }
)
```

在庫の減算と注文の作成を同時に確定させたいときは、マルチドキュメントトランザクションを使います。トランザクションはレプリカセットかシャードクラスタでしか動かないため、ローカルで試すなら`mongod --replSet rs0`で起動し、mongoshで`rs.initiate()`を1回実行しておきます。

```
const session = db.getMongo().startSession()
const shop = session.getDatabase("shop")
session.startTransaction({ writeConcern: { w: "majority" } })
try {
  const r = shop.inventory.updateOne(
    { sku: "A-100", qty: { $gte: 1 } },
    { $inc: { qty: -1 } }
  )
  if (r.modifiedCount === 0) throw new Error("在庫不足")
  shop.orders.insertOne({ sku: "A-100", qty: 1, createdAt: new Date() })
  session.commitTransaction()
} catch (e) {
  session.abortTransaction()
  throw e
} finally {
  session.endSession()
}
```

`updateOne`は条件に一致しなくてもエラーを返さないため、`modifiedCount`を確かめて明示的に中断しています。このような処理が業務の大半を占めるなら、前の章の判定どおりRDBを選ぶ方が素直です。

## MongoDBのバージョン・サポート期限とエコシステム：2026年10月時点の選び方

導入判断では、技術特性に加えてライセンスとバージョン方針を押さえておく必要があります。ここは情報が古くなりやすいため、2026年10月10日時点で公式ページを確認した事実だけで整理します。

### 現行9.0系と8.0系・7.0系のサポート終了日から決める新規構築の版

[公式のRelease Notes](https://www.mongodb.com/docs/manual/release-notes/)では、現行の安定版は9.0系と案内されています。各系列のサポート終了日は、[MongoDBのソフトウェアライフサイクル表](https://www.mongodb.com/legal/support-policy/lifecycles)（MongoDB Serverの欄）で次のとおりです。

| 系列   | リリース     | サポート終了日        |
| ---- | -------- | -------------- |
| 9.0系 | 2026年9月  | 2031年10月31日    |
| 8.0系 | 2024年10月 | 2029年10月31日    |
| 7.0系 | 2023年8月  | 2027年8月31日     |
| 6.0系 | 2022年7月  | 2025年7月31日（終了） |

新規構築では、サポート期間に余裕のある9.0系か8.0系を選びます。9.0系は出たばかりなので、使うドライバやODMの対応状況を確かめてから採用し、確認が済むまでは8.0系で始めるのが堅実です。7.0系以前で動いている既存システムは、残り期間から逆算してアップグレード計画を立ててください。メジャーバージョンは段階的に上げるのが公式の手順で、各版のリリースノートにある前提条件（機能互換性バージョンの設定など）を順に満たす必要があります。

### Realm・Atlas Device Sync終了でモバイル同期を前提にできない現状

かつてMongoDBはモバイル向けにRealmローカルDBとAtlas Device Sync（端末とクラウドの自動同期）を提供していましたが、この同期サービスは**2024年9月に非推奨が告知され、2025年9月30日に停止**しました。古い解説記事の多くが「Realmでオフライン同期ができる」と書いていますが、クラウド同期機能は現在提供されていません（クライアント側のローカルDB実装はオープンソースとして残存）。モバイルのオフライン同期を前提に採用を検討している場合は、この点を最新情報として確認する必要があります。残ったローカルDB側の現在地と移行の判断軸は、[Realm（モバイルDB）とはを解説した記事](https://www.issoh.co.jp/tech/details/15808/)で詳しく扱っています。

### mongosh・Compass・Atlasなど管理ツールと言語ドライバ・ODMの選び方

日常の操作には次のツールを使います。用途で選べば十分です。

- **mongosh**：公式のコマンドラインシェル。CRUDや管理コマンドを直接実行する。
- **MongoDB Compass**：公式GUI。ドキュメントの閲覧・編集、クエリ、インデックス作成、実行計画の確認をコード無しで行える。
- **MongoDB Atlas**：AWS・Google Cloud・Azure上で動く公式マネージドサービス。バックアップや監視、パッチ適用が組み込まれ、無料枠もある。階層と料金と接続経路の選び方は[MongoDB Atlasとは](https://www.issoh.co.jp/tech/details/16446/)にまとめている。

アプリ開発では、Node.js公式ドライバやPythonの`PyMongo`から接続します。Node.jsではスキーマ定義とバリデーションを担うODMの[Mongoose](https://www.issoh.co.jp/tech/details/3588/)がよく使われます。スキーマ変更を安全に反映する[Spring BootとFlywayによるマイグレーション](https://www.issoh.co.jp/tech/details/2314/)のような運用面の整備も、本番運用では欠かすと後で困る部分です。

## MongoDBの学習リソース：公式マニュアルと無料クラスタで手を動かす順序

体系的に学ぶなら、無料の公式学習サイト**MongoDB University**のコースと、常に最新が反映される**公式ドキュメント（MongoDB Manual）**が中心になります。実際に手を動かす段階では、Atlasの無料クラスタを1つ作り、mongoshやCompassから前述のCRUDを試すのが最短です。トランザクションまで試すなら、Atlasの無料クラスタはレプリカセット構成なので、ローカルで`rs.initiate()`を打つ手間も省けます。

つまずいた点はMongoDB公式コミュニティフォーラムで解決例を探せます。読むだけで終えず、小さなコレクションに数件のドキュメントを入れて、検索・更新・検証ルールの違反まで一通り通すと、ドキュメントモデルの感覚と「どこで使ってはいけないか」の勘所が同時に身につきます。

## よくある質問

MongoDBの採用可否と基本仕様について、よく確認される点をまとめます。

### MongoDBを使ってはいけないのはどんな場合ですか？

複数のデータを厳密な整合性で同時更新する会計・在庫引当・決済が業務の中心にある場合と、正規化された多対多の結合や帳票集計が中心の基幹システムです。MongoDBもトランザクションに対応していますが、公式マニュアルはスキーマ設計の代わりにはならないとしており、既定で1分未満という実行時間の制約もあります。データが小規模で表形式に収まるだけなら、MySQLやPostgreSQLで十分なことが多いです。

### MongoDBはデータが消える・流出すると言われるのは本当ですか？

多くは初期の既定値に由来する評判です。現行では、レプリカセットの既定の書き込み保証はmajorityで、mongodは既定でlocalhostにしか待ち受けません。ただし、アプリでw: 0やw: 1を指定する、bindIpを0.0.0.0に広げて認証を切る、サポート切れの版を外部到達可能なまま動かす、といった運用をすれば今も事故は起きます。2025年12月のMongoBleed（CVE-2025-14847）のように、旧版の放置がそのまま情報漏えいにつながった例もあります。

### MongoDBは無料で使えますか？オープンソースですか？

自社利用であれば、Community Editionを無料で使えます。ただしライセンスはSSPLで、MongoDB自身のFAQがOSIの承認を受けていないと明記しているため、OSIの定義でのオープンソースではありません。MongoDBそのものをデータベースサービスとして外部提供する用途には、サービス提供に使うソフトウェアのソース公開という条件が付きます。運用込みで任せたい場合は、無料枠のあるMongoDB Atlasが選択肢です。

### MongoDBのドキュメントの最大サイズはどれくらいですか？

1つのBSONドキュメントは最大16MiB（16メビバイト）で、入れ子の深さは100階層までです。これを超えるデータは、GridFSでチャンクに分割して保存します。コメントやログのように際限なく伸びる配列を1ドキュメントに持たせる設計は、この上限に達しやすいため、別コレクションに分けて参照で結ぶ形にします。

### MongoDBとMySQLの違いは何ですか？どちらを選べばよいですか？

MySQLは行と列の表と固定スキーマ、厳密なトランザクションとJOINが強みのRDBです。MongoDBはドキュメント（BSON）と可変スキーマ、シャーディングによる水平スケールが強みのNoSQLです。項目が一定でない大量データを1件単位で読み書きするならMongoDB、整合性と結合・集計が中心の業務ならMySQLが向きます。一部の項目だけが可変なら、PostgreSQLのJSONB列で受ける方法もあります。

## 関連記事

- [MongoDBのインデックスの種類とそれぞれの特徴](https://www.issoh.co.jp/tech/details/2626/)：ESR原則と複合インデックスの設計
- [Mongooseの基本的な概念と使用方法](https://www.issoh.co.jp/tech/details/3588/)：Node.jsでスキーマを定義するODM
- [Spring BootとFlywayを使用したマイグレーション設定方法](https://www.issoh.co.jp/tech/details/2314/)：スキーマ変更の運用
- [MongoDBの脆弱性CVE-2025-14847（MongoBleed）](https://www.issoh.co.jp/tech/details/10540/)：影響版と確認手順
- [ArangoDBの主要機能と他のデータベースにはない強み](https://www.issoh.co.jp/tech/details/7760/)：マルチモデルDBとの比較

---

出典: [MongoDBは使ってはいけない？向かない業務の判断基準とドキュメント構造・使い方入門](<https://www.issoh.co.jp/column/details/3006/>)（株式会社一創）
