MongoDB

ドキュメント指向データベース

MongoDBはドキュメント指向のNoSQLデータベース。 JSONライクなBSON形式でデータを格納し、柔軟なスキーマ、 豊富なクエリ機能、水平スケーラビリティを提供します。

データモデル

Database

データベース

Collection

テーブル相当

Document

行相当(BSON)

1// ドキュメントの例
2{
3 "_id": ObjectId("507f1f77bcf86cd799439011"),
4 "name": "Alice",
5 "email": "alice@example.com",
6 "age": 30,
7 "address": {
8 "city": "Tokyo",
9 "zip": "100-0001"
10 },
11 "tags": ["developer", "mongodb"],
12 "createdAt": ISODate("2024-01-15T10:30:00Z")
13}

埋め込み(Embedding)

関連データを1つのドキュメントに含める。 1:1、1:少数の関係に適する。読み取りが高速。

参照(Reference)

他ドキュメントのIDを保持。 1:多、多:多の関係に適する。データの重複を避ける。

CRUD操作

1// Create
2db.users.insertOne({ name: "Alice", age: 30 })
3db.users.insertMany([{ name: "Bob" }, { name: "Carol" }])
4
5// Read
6db.users.find({ age: { $gte: 25 } })
7db.users.findOne({ email: "alice@example.com" })
8db.users.find({ tags: "mongodb" }).sort({ createdAt: -1 }).limit(10)
9
10// Update
11db.users.updateOne(
12 { _id: ObjectId("...") },
13 { $set: { age: 31 }, $push: { tags: "expert" } }
14)
15db.users.updateMany({ status: "inactive" }, { $set: { archived: true } })
16
17// Delete
18db.users.deleteOne({ _id: ObjectId("...") })
19db.users.deleteMany({ status: "deleted" })
20
21// クエリ演算子
22$eq, $ne, $gt, $gte, $lt, $lte // 比較
23$in, $nin // 配列内の値
24$and, $or, $not // 論理
25$exists, $type // フィールド
26$regex // 正規表現

インデックス

1// 単一フィールド
2db.users.createIndex({ email: 1 })
3
4// 複合インデックス
5db.orders.createIndex({ userId: 1, createdAt: -1 })
6
7// ユニークインデックス
8db.users.createIndex({ email: 1 }, { unique: true })
9
10// TTLインデックス(自動削除)
11db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })
12
13// テキストインデックス
14db.articles.createIndex({ title: "text", content: "text" })
15
16// 地理空間インデックス
17db.places.createIndex({ location: "2dsphere" })
18
19// インデックス確認
20db.users.getIndexes()
21
22// 実行計画
23db.users.find({ email: "test@example.com" }).explain("executionStats")

集計パイプライン

1db.orders.aggregate([
2 // ステージ1: フィルタ
3 { $match: { status: "completed", createdAt: { $gte: ISODate("2024-01-01") } } },
4
5 // ステージ2: グループ化
6 { $group: {
7 _id: "$userId",
8 totalAmount: { $sum: "$amount" },
9 orderCount: { $sum: 1 }
10 }},
11
12 // ステージ3: ソート
13 { $sort: { totalAmount: -1 } },
14
15 // ステージ4: 上位10件
16 { $limit: 10 },
17
18 // ステージ5: JOIN相当
19 { $lookup: {
20 from: "users",
21 localField: "_id",
22 foreignField: "_id",
23 as: "user"
24 }},
25
26 // ステージ6: 出力形式
27 { $project: {
28 userId: "$_id",
29 totalAmount: 1,
30 userName: { $arrayElemAt: ["$user.name", 0] }
31 }}
32])

レプリカセット

レプリカセットは高可用性のための複製構成。 1つのPrimaryと複数のSecondaryで構成。自動フェイルオーバー。

Primary

Write/Read

→ 複製
Secondary

Read

Secondary

Read

Read Preference

  • primary: Primaryのみ(デフォルト)
  • secondary: Secondaryのみ
  • primaryPreferred: Primary優先
  • nearest: 最も近いノード

Write Concern

  • w: 1: Primaryのみ確認
  • w: majority: 過半数確認
  • j: true: ジャーナル書き込み確認

SRE/インフラ観点

パフォーマンス

  • • 適切なインデックス設計
  • • ドキュメントサイズは16MB制限
  • • 埋め込み vs 参照のトレードオフ
  • • Working Setがメモリに収まるように

監視項目

  • • レプリケーション遅延(replication lag)
  • • 接続数、オープンカーソル数
  • • Page Faults(メモリ不足の兆候)
  • • スローオペレーションログ

運用Tips

  • • レプリカセットは最低3ノード(奇数)
  • • バックアップは mongodump または スナップショット
  • • Atlas(マネージドサービス)の検討