CheatSheet
日本語 icon日本語English iconEnglish
チートシートとはカンニングペーパーのことです。それが転じて、本来覚えることをまとめておいたものです。
要点をすぐに参照できるようにまとめてみました。

MongoDB

エンジニアのためのWebチートシート

MongoDBは、ドキュメント指向のNoSQLデータベースです。 JSON風のドキュメントを柔軟に格納でき、スケーラビリティに優れています。 CRUD操作、クエリ・更新演算子、集約パイプライン、インデックス、データモデリングなどをチートシートにまとめました。

mongosh コマンド

接続

  • mongosh でデータベースに接続する方法です。

    # ローカル接続(localhost:27017)
    mongosh
    
    # URI指定
    mongosh "mongodb://localhost:27017/mydb"
    
    # ユーザー認証付き
    mongosh "mongodb://user:pass@host:27017/mydb"
    
    # MongoDB Atlas
    mongosh "mongodb+srv://cluster.mongodb.net/mydb" \
      --username myuser

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

  • データベースとコレクションの操作です。

    // データベース操作
    show dbs                      // DB一覧
    db                            // 現在のDB名
    use myDatabase                // DB切替(なければ作成)
    db.dropDatabase()             // DB削除
    
    // コレクション操作
    show collections              // コレクション一覧
    db.createCollection("users")  // 作成
    db.users.drop()               // 削除
    db.users.renameCollection("members") // 名前変更

ヘルパーコマンド

  • よく使うヘルパーメソッドです。

    // 統計情報
    db.stats()                    // DB統計
    db.users.stats()              // コレクション統計
    db.serverStatus()             // サーバー状態
    
    // カウント
    db.users.countDocuments({})
    db.users.estimatedDocumentCount()
    
    // Distinct(ユニーク値)
    db.users.distinct("status")
    
    // ファイル実行
    load("script.js")
    
    // 終了
    quit()

CRUD操作

Create(作成)

  • ドキュメントの挿入です。

    // 1件挿入
    db.users.insertOne({
      name: "Alice",
      email: "alice@example.com",
      age: 30,
      tags: ["developer", "mongodb"],
      createdAt: new Date()
    })
    
    // 複数挿入
    db.users.insertMany([
      { name: "Bob", age: 25, status: "active" },
      { name: "Charlie", age: 35, status: "active" }
    ])
    
    // ordered: false で挿入エラーをスキップして続行
    db.users.insertMany(
      [{ _id: 1, name: "A" }, { _id: 1, name: "B" }, { _id: 2, name: "C" }],
      { ordered: false }
    )
    // _id: 1 の重複エラーをスキップし、_id: 2 は挿入される

Read(読み取り)

  • ドキュメントの検索です。

    // 全件取得
    db.users.find()
    
    // 条件付き
    db.users.find({ age: { $gt: 25 } })
    
    // 1件のみ
    db.users.findOne({ name: "Alice" })
    
    // プロジェクション(フィールド選択)
    db.users.find(
      {},
      { name: 1, email: 1, _id: 0 }
    )
    
    // ソート・スキップ・リミット
    db.users.find()
      .sort({ age: -1 })   // 降順
      .skip(10)             // 10件スキップ
      .limit(5)             // 5件取得
    
    // 整形表示
    db.users.find().pretty()

Update & Delete

  • ドキュメントの更新と削除です。

    // 1件更新
    db.users.updateOne(
      { name: "Alice" },
      { $set: { age: 31 } }
    )
    
    // 複数更新
    db.users.updateMany(
      { status: "inactive" },
      { $set: { archived: true } }
    )
    
    // Upsert(なければ挿入)
    db.users.updateOne(
      { email: "new@example.com" },
      { $set: { name: "New User" } },
      { upsert: true }
    )
    
    // findOneAndUpdate(更新後の値を返す)
    db.users.findOneAndUpdate(
      { name: "Alice" },
      { $inc: { age: 1 } },
      { returnDocument: "after" }
    )
    
    // replaceOne(ドキュメント全体を置換)
    db.users.replaceOne(
      { name: "Alice" },
      { name: "Alice", age: 32, role: "admin" }
    )
    
    // 削除
    db.users.deleteOne({ name: "Bob" })
    db.users.deleteMany({ status: "inactive" })

クエリ演算子

比較演算子と論理演算子の一覧です。

演算子説明
$eq

等しい — { age: { $eq: 30 } } ※ { age: 30 } と同等

$ne

等しくない — { status: { $ne: "deleted" } }

$gt / $gte

より大きい / 以上 — { age: { $gte: 20 } }

$lt / $lte

より小さい / 以下 — { age: { $lt: 40 } }

$in / $nin

いずれかに一致 / 不一致 — { status: { $in: ["active", "pending"] } }

$and

全条件を満たす(暗黙的ANDも可)

$or

いずれかを満たす — { $or: [{ a: 1 }, { b: 2 }] }

$not / $nor

条件を否定 / いずれも満たさない

要素 & 評価演算子

  • フィールドの存在チェック、正規表現、テキスト検索です。

    // $exists: フィールドの存在チェック
    db.users.find({ email: { $exists: true } })
    db.users.find({ deletedAt: { $exists: false } })
    
    // $type: BSONタイプ判定
    db.users.find({ age: { $type: "number" } })
    db.data.find({ value: { $type: "string" } })
    
    // $regex: 正規表現マッチ
    db.users.find({ name: { $regex: /^A/, $options: "i" } })
    db.users.find({
      email: { $regex: "example\.com$" }
    })
    
    // $text: テキスト検索(テキストインデックス必要)
    db.posts.find({
      $text: { $search: "mongodb tutorial" }
    })
    
    // $expr: 集約式をクエリで使用
    db.orders.find({
      $expr: { $gt: ["$total", "$budget"] }
    })

配列演算子

  • 配列フィールドに対するクエリ演算子です。

    // $all: 全要素を含む
    db.posts.find({
      tags: { $all: ["mongodb", "nosql"] }
    })
    
    // $elemMatch: 条件に一致する要素がある
    db.students.find({
      scores: { $elemMatch: { $gte: 80, $lt: 90 } }
    })
    
    // $size: 配列のサイズ
    db.posts.find({ tags: { $size: 3 } })
    
    // 配列内の要素で直接検索
    db.posts.find({ tags: "mongodb" })
    
    // ネストしたドキュメント配列の検索
    db.orders.find({
      "items.name": "Book"
    })
    
    // ドット記法で配列のインデックス指定
    db.users.find({ "scores.0": { $gte: 80 } })

更新演算子

フィールドの値を変更する演算子の一覧です。

演算子説明
$set

フィールドの値を設定 — { $set: { name: "Alice" } }

$unset

フィールドを削除 — { $unset: { tmp: "" } }

$rename

フィールド名を変更 — { $rename: { "old": "new" } }

$inc

数値を加算 — { $inc: { views: 1 } }

$mul

数値を乗算 — { $mul: { price: 1.1 } }

$min / $max

現在値より小さい/大きい場合のみ更新

$currentDate

現在日時を設定 — { $currentDate: { updatedAt: true } }

配列更新演算子

  • 配列フィールドを変更する演算子です。

    // $push: 要素を追加
    { $push: { tags: "new" } }
    
    // $addToSet: 重複なしで追加
    { $addToSet: { tags: "unique" } }
    
    // $pull: 条件一致の要素を削除
    { $pull: { tags: "old" } }
    
    // $pop: 先頭(-1) or 末尾(1) を削除
    { $pop: { tags: 1 } }
    
    // $pullAll: 複数要素を一括削除
    { $pullAll: { tags: ["a", "b"] } }
    
    // $each: 複数要素を一度に追加
    { $push: { tags: { $each: ["a", "b", "c"] } } }
    
    // $each + $sort + $slice
    // ソート後に先頭N件のみ保持
    db.users.updateOne(
      { _id: 1 },
      { $push: {
          scores: {
            $each: [90, 85],
            $sort: -1,
            $slice: 5
          }
      }}
    )

位置演算子 & arrayFilters

  • 配列内の特定要素を更新する演算子です。

    // $: 条件に一致した最初の要素を更新
    db.users.updateOne(
      { "scores.subject": "math" },
      { $set: { "scores.$.grade": "A" } }
    )
    
    // $[]: 全要素を更新
    db.users.updateMany(
      {},
      { $inc: { "scores.$[].value": 5 } }
    )
    
    // $[<identifier>]: arrayFiltersで条件指定
    db.users.updateMany(
      {},
      { $set: { "scores.$[elem].passed": true } },
      { arrayFilters: [{ "elem.value": { $gte: 60 } }] }
    )
    
    // ネストした配列の更新
    db.posts.updateOne(
      { _id: 1 },
      { $push: { "comments.$[c].replies": { text: "reply" } } },
      { arrayFilters: [{ "c.author": "Alice" }] }
    )

集約パイプライン

基本ステージ

  • $match, $group, $sort, $project, $limit の基本です。

    db.orders.aggregate([
      // $match: フィルタリング
      { $match: { status: "completed" } },
    
      // $group: グループ化と集計
      { $group: {
          _id: "$customerId",
          totalAmount: { $sum: "$amount" },
          avgAmount: { $avg: "$amount" },
          count: { $sum: 1 },
          maxAmount: { $max: "$amount" },
          items: { $push: "$item" }
      }},
    
      // $sort: ソート
      { $sort: { totalAmount: -1 } },
    
      // $limit / $skip
      { $skip: 10 },
      { $limit: 5 },
    
      // $project: フィールド選択・変換
      { $project: {
          _id: 0,
          customer: "$_id",
          totalAmount: 1,
          avgAmount: { $round: ["$avgAmount", 2] }
      }}
    ])
    
    // $addFields: フィールドを追加
    { $addFields: {
        fullName: { $concat: ["$first", " ", "$last"] }
    }}

$lookup & $unwind

  • コレクション結合と配列展開です。

    // $lookup: コレクション結合(LEFT OUTER JOIN)
    db.orders.aggregate([
      { $lookup: {
          from: "users",          // 結合先
          localField: "userId",   // ordersのフィールド
          foreignField: "_id",    // usersのフィールド
          as: "userInfo"          // 結果の配列名
      }},
      // $unwind: 配列を展開(1ドキュメントに)
      { $unwind: "$userInfo" }
    ])
    
    // $unwind でタグのカウント
    db.posts.aggregate([
      { $unwind: "$tags" },
      { $group: {
          _id: "$tags",
          count: { $sum: 1 }
      }},
      { $sort: { count: -1 } }
    ])
    
    // 空配列のドキュメントも保持
    { $unwind: {
        path: "$tags",
        preserveNullAndEmptyArrays: true
    }}
    
    // $lookup + パイプライン(高度な結合)
    { $lookup: {
        from: "orders",
        let: { userId: "$_id" },
        pipeline: [
          { $match: { $expr: {
              $eq: ["$userId", "$$userId"]
          }}},
          { $sort: { createdAt: -1 } },
          { $limit: 3 }
        ],
        as: "recentOrders"
    }}

$facet & $bucket

  • 複数パイプラインの並列実行とバケット集計です。

    // $facet: 複数パイプラインを並列実行
    db.products.aggregate([
      { $facet: {
          priceStats: [
            { $group: {
                _id: null,
                avg: { $avg: "$price" },
                max: { $max: "$price" }
            }}
          ],
          categoryCount: [
            { $group: { _id: "$category", count: { $sum: 1 } } },
            { $sort: { count: -1 } }
          ],
          topProducts: [
            { $sort: { sales: -1 } },
            { $limit: 5 },
            { $project: { name: 1, sales: 1 } }
          ]
      }}
    ])
    
    // $bucket: バケット集計
    { $bucket: {
        groupBy: "$age",
        boundaries: [0, 20, 40, 60, 80],
        default: "Other",
        output: {
          count: { $sum: 1 },
          avgIncome: { $avg: "$income" }
        }
    }}
    
    // $out: 結果を新コレクションに書き出し
    { $out: "monthlySummary" }
    
    // $merge: 既存コレクションにマージ
    { $merge: {
        into: "summary",
        on: "_id",
        whenMatched: "replace",
        whenNotMatched: "insert"
    }}

インデックス

MongoDB がサポートするインデックス種類の一覧です。

種類用途
単一フィールド

1つのフィールドの等値・範囲検索

複合

複数フィールドの組み合わせ検索

マルチキー

配列フィールド(自動作成)

テキスト

全文検索($text クエリ)

TTL

一定時間後にドキュメントを自動削除

ユニーク

フィールド値の一意性を保証

部分

条件を満たすドキュメントのみインデックス

ワイルドカード

動的フィールドに対応(スキーマレス向け)

インデックス作成

  • 用途別のインデックス作成パターンです。

    // 単一フィールド
    db.users.createIndex({ email: 1 })       // 昇順
    db.users.createIndex({ createdAt: -1 })  // 降順
    
    // 複合インデックス
    db.orders.createIndex({
      customerId: 1, orderDate: -1
    })
    
    // ユニークインデックス
    db.users.createIndex(
      { email: 1 },
      { unique: true }
    )
    
    // テキストインデックス
    db.posts.createIndex({
      title: "text", content: "text"
    })
    
    // TTLインデックス(1時間後に自動削除)
    db.sessions.createIndex(
      { createdAt: 1 },
      { expireAfterSeconds: 3600 }
    )
    
    // 部分インデックス
    db.orders.createIndex(
      { status: 1 },
      { partialFilterExpression: { status: "active" } }
    )
    
    // ワイルドカードインデックス
    db.data.createIndex({ "$**": 1 })

explain & 統計

  • クエリの実行計画とパフォーマンス確認です。

    // 実行計画の確認
    db.users.find({ email: "test@example.com" })
      .explain("executionStats")
    
    // 確認すべきポイント
    // - winningPlan.stage: IXSCAN(インデックス使用)
    //   vs COLLSCAN(フルスキャン = 遅い)
    // - totalDocsExamined: 検査したドキュメント数
    // - executionTimeMillis: 実行時間
    
    // インデックス一覧
    db.users.getIndexes()
    
    // インデックス削除
    db.users.dropIndex("email_1")
    
    // 全インデックス削除(_id以外)
    db.users.dropIndexes()
    
    // インデックス一時無効化/再有効化
    db.users.hideIndex("email_1")
    db.users.unhideIndex("email_1")
    
    // インデックスサイズ
    db.users.stats().totalIndexSize
    
    // コレクションのストレージ情報
    db.users.stats({ scale: 1024 }) // KB単位

データモデリング

埋め込み vs 参照

  • データモデリングの2つのアプローチです。

    // ── 埋め込み(Embedding)──
    // 1:1 または 1:少数 の関係に適する
    // メリット: 1回のクエリ、アトミックな更新
    // デメリット: 16MB上限、データ重複の可能性
    db.users.insertOne({
      name: "Alice",
      address: {
        city: "Tokyo",
        zip: "100-0001"
      },
      orders: [
        { item: "Book", price: 1500 },
        { item: "Pen", price: 200 }
      ]
    })
    
    // ── 参照(Referencing)──
    // 1:多数 または 多:多 の関係に適する
    // メリット: データ重複なし、独立クエリ可能
    // デメリット: $lookup で結合が必要
    // users
    { _id: ObjectId("user1"), name: "Alice" }
    // orders(userId で参照)
    {
      _id: ObjectId("order1"),
      userId: ObjectId("user1"),
      item: "Book",
      total: 1500
    }
    
    // $lookup で結合して取得
    db.users.aggregate([
      { $lookup: {
          from: "orders",
          localField: "_id",
          foreignField: "userId",
          as: "orders"
      }}
    ])

スキーマバリデーション

  • JSONスキーマによるドキュメントの検証ルールです。

    // スキーマバリデーション付きコレクション作成
    db.createCollection("users", {
      validator: {
        $jsonSchema: {
          bsonType: "object",
          required: ["name", "email", "age"],
          properties: {
            name: {
              bsonType: "string",
              description: "must be a string"
            },
            email: {
              bsonType: "string",
              pattern: "^.+@.+$"
            },
            age: {
              bsonType: "int",
              minimum: 0,
              maximum: 150
            },
            status: {
              enum: ["active", "inactive", "banned"]
            }
          }
        }
      }
    })
    
    // 既存コレクションにバリデーション追加
    db.runCommand({
      collMod: "users",
      validator: { $jsonSchema: { /* ... */ } },
      validationLevel: "moderate",   // 既存は無視
      validationAction: "warn"       // 警告のみ
    })

トランザクション & 運用

トランザクション

  • 複数操作のアトミック実行です。

    // マルチドキュメントトランザクション
    const session = db.getMongo().startSession()
    session.startTransaction()
    
    try {
      db.accounts.updateOne(
        { _id: "A" },
        { $inc: { balance: -100 } },
        { session }
      )
      db.accounts.updateOne(
        { _id: "B" },
        { $inc: { balance: 100 } },
        { session }
      )
      session.commitTransaction()
    } catch (error) {
      session.abortTransaction()
      print("Aborted: " + error)
    } finally {
      session.endSession()
    }
    
    // 注意:
    // - レプリカセットまたはシャードクラスタが必要
    // - 単一ドキュメントの操作はデフォルトでアトミック
    // - トランザクションは60秒のタイムアウトあり

ユーザー管理

  • ユーザーの作成と権限設定です。

    // ユーザー作成
    db.createUser({
      user: "appUser",
      pwd: "securePassword",
      roles: [
        { role: "readWrite", db: "myApp" },
        { role: "read", db: "reporting" }
      ]
    })
    
    // 主要なビルトインロール
    // read         : 読み取り専用
    // readWrite    : 読み書き
    // dbAdmin      : DB管理(インデックス、統計)
    // userAdmin    : ユーザー管理
    // clusterAdmin : クラスタ管理
    // root         : 全権限
    
    // ユーザー削除
    db.dropUser("appUser")
    
    // パスワード変更
    db.changeUserPassword("appUser", "newPassword")
    
    // 権限変更
    db.grantRolesToUser("appUser", [
      { role: "dbAdmin", db: "myApp" }
    ])
    db.revokeRolesFromUser("appUser", [
      { role: "read", db: "reporting" }
    ])

引用・参考リンク

Related Goods

  • MongoDBの基礎から実践レベルまでを1冊で学べる究極の入門書。
セットアップからCRUD操作、設計パターンまで網羅しています。
    MongoDBの基礎から実践レベルまでを1冊で学べる究極の入門書。 セットアップからCRUD操作、設計パターンまで網羅しています。
    詳細をみる
  • RDB経験者がMongoDBに入門するのに最適な一冊。
RDBとの違いを踏まえた実践的な構築・運用方法を解説しています。
    RDB経験者がMongoDBに入門するのに最適な一冊。 RDBとの違いを踏まえた実践的な構築・運用方法を解説しています。
    詳細をみる
  • ケーブルに取り付け可能なTypeCとLightningの変換アダプタです。
スタイリッシュなデザインで、Apple製品との相性抜群です。
    ケーブルに取り付け可能なTypeCとLightningの変換アダプタです。 スタイリッシュなデザインで、Apple製品との相性抜群です。
    詳細をみる
  • お気に入りのサウンドデバイスをすぐ取り出せる位置にディスプレイさせておくことができます。
    お気に入りのサウンドデバイスをすぐ取り出せる位置にディスプレイさせておくことができます。
    詳細をみる

WebTerm - Recommended tools

WebTermは、ブラウザでLinuxコマンド・Gitコマンドを安全に実行でき、チュートリアル式で学べるターミナルサンドボックスです。
AIコーディングツールの普及に伴い、CLIの基礎知識を身につける重要性は増しています。実際のターミナルを操作するのに抵抗がある方でも、WebTermはローカル環境を壊す心配がありません。「会員登録不要・無料」で利用でき、学習環境として最適です。

WebTerm Logo

WebTerm

Browser Terminal Sandbox for Learning CLI

開く

All Cheatsheets

エンジニア・プログラマー向けの便利なチートシートを多数まとめています(SP/Tablet/PC対応)
すべてのチートシートを見る