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 2 db.users.insertOne({ name: "Alice", age: 30 }) 3 db.users.insertMany([{ name: "Bob" }, { name: "Carol" }]) 4 5 // Read 6 db.users.find({ age: { $gte: 25 } }) 7 db.users.findOne({ email: "alice@example.com" }) 8 db.users.find({ tags: "mongodb" }).sort({ createdAt: -1 }).limit(10) 9 10 // Update 11 db.users.updateOne( 12 { _id: ObjectId("...") }, 13 { $set: { age: 31 }, $push: { tags: "expert" } } 14 ) 15 db.users.updateMany({ status: "inactive" }, { $set: { archived: true } }) 16 17 // Delete 18 db.users.deleteOne({ _id: ObjectId("...") }) 19 db.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 // 単一フィールド 2 db.users.createIndex({ email: 1 }) 3 4 // 複合インデックス 5 db.orders.createIndex({ userId: 1, createdAt: -1 }) 6 7 // ユニークインデックス 8 db.users.createIndex({ email: 1 }, { unique: true }) 9 10 // TTLインデックス(自動削除) 11 db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 }) 12 13 // テキストインデックス 14 db.articles.createIndex({ title: "text", content: "text" }) 15 16 // 地理空間インデックス 17 db.places.createIndex({ location: "2dsphere" }) 18 19 // インデックス確認 20 db.users.getIndexes() 21 22 // 実行計画 23 db.users.find({ email: "test@example.com" }).explain("executionStats")
集計パイプライン
1 db.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(マネージドサービス)の検討