MongoDB: インデックスタイプと高度機能

最終更新:2026-08-26

高度なインデキシング機能—TTL、部分、ESRルールを習得し、本番グレードのインデックスシステムを構築。

1. 学習内容


100%
graph TB
    A[インデックスタイプ] --> B[unique<br/>一意インデックス]
    A --> C[sparse<br/>スパースインデックス]
    A --> D[TTL<br/>自動期限切れ]
    A --> E[partial<br/>部分インデックス]
    A --> F[compound<br/>複合インデックス]

    B --> B1[一意性を保証<br/>重複でエラー]
    C --> C1[nullをスキップ<br/>スペース節約]
    D --> D1[自動削除<br/>定期クリーンアップ]
    E --> E1[条件を満たすドキュメントのみ<br/>パフォーマンス+節約]

    style D fill:#d4edda
    style E fill:#d4edda

2. 一意インデックス(unique)

概念説明: 一意インデックスは、インデックスフィールドの値がコレクション全体で一意であることを保証し、データベースレベルでデータ整合性を保証します。アプリケーション層のバリデーションとは異なり、一意インデックスはデータベースエンジンによって強制されます—どのクライアントが書き込んでも重複値は拒否されます。

動作原理: 一意インデックスはB+ツリー内で一意性制約を強制します。挿入または更新が発生するたび、エンジンはまず同じ値のキーがインデックスに既に存在するかチェックし、存在すればE11000 duplicate key error例外をスローします。複合一意インデックスは、フィールドの組み合わせが一意であることを要求します(各フィールド単独は重複可能)。

使用用途:

次元 通常インデックス 一意インデックス
値の制約 重複許可 重複不可
挿入チェック B+ツリー更新のみ B+ツリー更新 + 一意性チェック
書き込みパフォーマンス ベースライン わずかに遅い(+5%の一意性オーバーヘッド)
エラーメッセージ なし E11000 duplicate key error
部分的一意 非サポート partialFilterExpressionで実装
JAVASCRIPT
// === 一意インデックス作成 ===
db.users.createIndex({ email: 1 }, { unique: true });
// emailフィールドの値は一意である必要がある

// === 複合一意インデックス ===
db.products.createIndex({ sku: 1, variant: 1 }, { unique: true });
// (sku, variant)の組み合わせが一意である必要がある

// === 一意インデックス + 選択フィールド ===
db.users.createIndex(
  { email: 1 },
  { unique: true, partialFilterExpression: { email: { $exists: true } } }
);
// emailフィールドが存在するドキュメントのみに一意制約を適用

要点分析:

  1. 一意インデックスはnull値の存在を許可するが、コレクション全体で1つのnullのみ(nullは同じ値と見なされる)
  2. partialFilterExpressionを使用すると、一意制約を一部ドキュメントのみに適用可能、nullの一意性問題を解決
  3. 一意インデックス作成前に、コレクションに重複値が存在してはならない、さもなければ作成失敗


3. スパースインデックス

概念説明: スパースインデックスは、インデックスフィールドを持ち、かつそのフィールドがnullでないドキュメントのみをインデックスし、フィールドが欠落またはnullのドキュメントをスキップします。通常インデックスは全ドキュメントをインデックス(欠落フィールドはnullとして扱う)するのに対し、スパースインデックスは無効エントリを除外してスペースを節約します。

動作原理: スパースインデックス作成時、エンジンはドキュメント挿入後にインデックスフィールドが存在しnullでないかチェックし、条件を満たす場合のみB+ツリーにインデックスエントリを追加します。クエリ時、スパースインデックスが使用される場合、結果にはフィールド欠落のドキュメントは含まれません(インデックスにないため)。

使用用途:

100%
graph LR
    subgraph "ドキュメントコレクション"
        D1["{sku:'A', discount:10}"]
        D2["{sku:'B'}"]
        D3["{sku:'C', discount:null}"]
        D4["{sku:'D', discount:20}"]
    end

    subgraph "通常インデックス"
        I1["A→D1, B→D2, C→D3, D→D4"]
    end

    subgraph "スパースインデックス"
        I2["10→D1, 20→D4<br/>(エントリ2件のみ)"]
    end

    style I2 fill:#d4edda
シナリオ 推奨 理由
フィールドがよく欠落(オプションフィールド) スパースインデックス 値を持つドキュメントのみインデックスでスペース節約
フィールドが常に値を持つ 通常インデックス スキップ不要、スパースの利点なし
一意 + 複数null許可 スパース一意インデックス nullは一意性チェックに含まれない
クエリがnullドキュメントを返す必要がある 通常インデックス スパースインデックスはnullドキュメントを除外
JAVASCRIPT
// === スパースインデックス:nullフィールドをスキップ ===
db.products.createIndex({ discount: 1 }, { sparse: true });
// discountフィールドを持つドキュメントのみインデックス

// === スパースインデックス vs 通常インデックス ===
// 通常インデックス:全ドキュメントをインデックス(null含む)
// スパースインデックス:非nullドキュメントのみインデックス

要点分析:

  1. スパースインデックスはフィールド欠落のドキュメントをカバーしない、find({discount: null})はフィールド欠落のドキュメントを返さない
  2. スパース + 一意の組み合わせ:複数ドキュメントがこのフィールドを欠落可能、既存値の一意性を確保
  3. 部分インデックスはスパースインデックスのスーパーセット(より柔軟)、部分インデックスを優先使用を推奨


4. TTLインデックス(自動期限切れ)

概念説明: TTL(Time-To-Live)インデックスはMongoDBの自動期限切れ・削除メカニズムで、日付フィールドに基づいて指定時間を超えたドキュメントを自動削除します。手動クリーンアップやスケジュールタスク不要、データベースエンジンがバックグラウンドで自動処理—セッション管理やログクリーンアップの強力なツール。

動作原理: TTLインデックスはB+ツリーにバックグラウンドクリーンアップスレッドを追加します。このスレッドは60秒ごとに実行し、インデックス内の日付フィールドをスキャンし、currentTime - fieldValue > expireAfterSecondsを計算し、期限切れドキュメントを全て削除。削除操作自体が書き込みオーバーヘッドを発生させ、大量の期限切れドキュメントは書き込み圧の急増を引き起こす可能性。

100%
sequenceDiagram
    participant App as アプリケーション
    participant TTL as TTLバックグラウンドスレッド
    participant IX as TTLインデックスB+ツリー
    participant DOC as ドキュメントコレクション

    App->>DOC: Insert {token:'abc', createdAt: T1}
    DOC->>IX: インデックスエントリ createdAt=T1

    note over TTL: 60秒ごと

    loop 60秒ごと
        TTL->>IX: createdAt値をスキャン
        IX-->>TTL: 全エントリを返す
        TTL->>TTL: 現在時刻 - createdAt を計算
        alt 期限切れ(> expireAfterSeconds)
            TTL->>DOC: 期限切れドキュメントを削除
            DOC->>IX: 対応するインデックスエントリを削除
        else 期限切れなし
            note over TTL: スキップ
        end
    end

使用用途:

シナリオ expireAfterSeconds 典型的な値
ユーザーセッション 30分 1,800
認証コード 10分 600
ログデータ 90日保持 7,776,000
一時トークン 1時間 3,600
レート制限ログ 1日 86,400

⚠️ TTLの制限:

制限 説明 解決策
複合インデックス不可 TTLは単一日付フィールドのみベース 複合条件には部分インデックス + アプリ層クリーンアップ
フィールドはDate型必須 Number/Stringは非サポート new Date()で時刻を保存
削除遅延 バックグラウンドスレッドは60秒ごとにスキャン 最大60秒遅延、時間は正確ではない
削除は正確性を保証しない 大量の期限切れドキュメントはバッチ削除の可能性 ビジネス層でフォールトトレランスを確保
JAVASCRIPT
// === TTLインデックス作成(30日後に自動削除)===
db.sessions.createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 30 * 24 * 60 * 60 }
);

// === TTL編集 ===
db.runCommand({
  collMod: 'sessions',
  index: { keyPattern: { createdAt: 1 }, expireAfterSeconds: 7 * 24 * 60 * 60 }
});

// === TTLキャンセル(falseに設定)===
db.runCommand({
  collMod: 'sessions',
  index: { keyPattern: { createdAt: 1 }, expireAfterSeconds: -1 }
});

典型的なシナリオ:



5. 部分インデックス

概念説明: 部分インデックスはフィルタ条件を満たすドキュメントのみをインデックスし、スパースインデックスの拡張版です。partialFilterExpressionでどのドキュメントをインデックスに含めるか指定し、スペース節約とインデックス精度向上の両方を実現、本番環境で最も推奨されるインデックス最適化手法の1つ。

動作原理: 部分インデックス作成時、エンジンはpartialFilterExpressionを満たすドキュメントのみB+ツリーに挿入します。クエリ時、オプティマイザはクエリ条件がpartialFilterExpressionを「カバー」する場合のみ(クエリ条件がフィルタ条件のサブセットまたは同等)このインデックスを選択し、さもなければ使用しません。

使用用途:

100%
graph TB
    subgraph "コレクション(10000ドキュメント)"
        A[全ドキュメント<br/>10000件]
    end

    subgraph "通常インデックス"
        B[インデックスエントリ<br/>10000件<br/>~10MB]
    end

    subgraph "部分インデックス<br/>isActive=true, stock>0"
        C[インデックスエントリ<br/>3000件<br/>~3MB]
    end

    A --> B
    A --> C

    style C fill:#d4edda
比較基準 通常インデックス 部分インデックス スパースインデックス
フィルタ条件 なし $eq/$gt/$gte/$lt/$lte/$exists/$type/$andをサポート フィールド存在のみ
スペース節約 0% 30–70% 欠落データの割合による
柔軟性 ベースライン ⭐⭐⭐ 最も柔軟 ⭐ 最も制限
クエリ制約 なし クエリ条件がフィルタ条件にマッチ必要 フィールド条件を含むクエリ必要
推奨 デフォルト ✅ 本番優先 シンプルなシナリオのみ
サポート
$eq / $gt / $gte / $lt / $lte
$exists: true
$type
$and
$or / $in / $nin
JAVASCRIPT
// === 部分インデックス:条件を満たすドキュメントのみインデックス ===
db.products.createIndex(
  { category: 1, price: 1 },
  {
    partialFilterExpression: {
      isActive: true,
      stock: { $gt: 0 }
    }
  }
);
// 現在販売中の商品のみインデックス(isActive=true, stock>0)

// === スペース節約インデックス ===
// 通常インデックス:全10000ドキュメントをインデックス
// 部分インデックス:現在販売中の3000商品のみインデックス(70%スペース節約)

▶ サンプル 1:部分インデックスの実践

JAVASCRIPT
// ShopHub:販売中かつ在庫のある商品のみインデックス、70%インデックススペース節約
db.products.insertMany([
  { sku: 'A001', category: 'Electronics', price: 599, isActive: true, stock: 50 },
  { sku: 'A002', category: 'Electronics', price: 299, isActive: false, stock: 0 },
  { sku: 'A003', category: 'Books', price: 29, isActive: true, stock: 100 },
  { sku: 'A004', category: 'Books', price: 49, isActive: true, stock: 0 }
]);

// 部分インデックスはisActive=true AND stock>0のドキュメントのみ(A001, A003)
db.products.createIndex(
  { category: 1, price: 1 },
  { partialFilterExpression: { isActive: true, stock: { $gt: 0 } } }
);

// クエリはfilter条件を含む必要がある
db.products.find({
  category: 'Electronics',
  isActive: true,
  stock: { $gt: 0 },
  price: { $gte: 100 }
}).explain();
// winningPlan.stage: IXSCAN ✅

// filter条件欠落 → インデックス不使用
db.products.find({ category: 'Electronics', price: { $gte: 100 } }).explain();
// winningPlan.stage: COLLSCAN(部分インデックスを使用しない)


6. ESRルール

Equality → Sort → Range:複合インデックスのフィールド順序に関する黄金律。

概念説明: ESRルールはMongoDBインデックス設計で最も重要なルールです。複合インデックスの最適なフィールド順序を指定:等価条件が最初、ソートフィールドが中央、範囲条件が最後。ESRルールに違反するとインデックス効率が大幅に低下したり、インデックスが無効になる可能性があります。

動作原理:

100%
graph TB
    subgraph "ESRインデックス {status, createdAt, price}"
        A["Equality: status='paid'<br/>→ 支払い済みドキュメントを特定"] --> B["Sort: createdAt: -1<br/>→ インデックスはソート済み、メモリソート不要"]
        B --> C["Range: price >= 100<br/>→ 範囲スキャン、後続フィールドを中断"]
    end

    subgraph "アンチパターン:RSEインデックス {price, status, createdAt}"
        D["Range: price >= 100<br/>→ 大量のインデックスエントリをスキャン"] --> E["Sort: status<br/>→ メモリベースのソートが必要"]
        E --> F["Equality: createdAt<br/>→ インデックスを使用できなくなった"]
    end

    style A fill:#d4edda
    style B fill:#cce5ff
    style C fill:#fff3cd
    style D fill:#f8d7da
    style E fill:#f8d7da
    style F fill:#f8d7da

ESRルール比較表:

順序 タイプ 機能
1番目 Equality category: 'Electronics' 迅速に絞り込み
2番目 Equality isActive: true さらに範囲を絞り込み
3番目 Sort sort: { createdAt: -1 } インデックスの順序性を活用しソート回避
4番目 Range price: { $gte: 100 } 範囲スキャン、最後に配置

ESR違反の結果:

誤った順序 結果 説明
RangeがEqualityより前 範囲スキャンが広すぎる totalKeysExaminedがnReturnedより大幅に大きい
SortがRangeより後 インデックスをソートに使用できない SORTステージ(メモリソート)が発生
EqualityをスキップしてSort直接 正確な開始点なしでソート 全インデックススキャン + ソート
JAVASCRIPT
// === 検索:等価フィルタ + ソート + 範囲 ===
db.products.find({
  category: 'Electronics',          // Equality
  isActive: true                    // Equality
}).sort({ createdAt: -1 })          // Sort
  .limit(20);

// 価格範囲
db.products.find({
  category: 'Electronics',
  createdAt: { $gte: new Date('2026-01-01') }  // Range
}).sort({ rating: -1 });

// === 最適インデックス ===
db.products.createIndex({
  category: 1,         // E - 等価フィルタ
  isActive: 1,         // E - 等価フィルタ
  createdAt: -1,       // S - ソート(方向マッチング)
  rating: -1           // R - 範囲(最後に配置)
});
順序 タイプ
1番目 Equality category: 'Electronics'
2番目 Equality isActive: true
3番目 Sort sort: { createdAt: -1 }
4番目 Range createdAt: { $gte: ... }

▶ サンプル 2:ESRルールの実践的比較

JAVASCRIPT
// TechCorp注文システム:ESR正しい順序 vs 誤った順序の実行プラン比較
db.orders.insertMany([
  { userId: 'user_001', status: 'paid', createdAt: new Date('2026-07-01'), total: 100 },
  { userId: 'user_002', status: 'pending', createdAt: new Date('2026-07-02'), total: 200 },
  { userId: 'user_001', status: 'paid', createdAt: new Date('2026-07-03'), total: 50 }
]);

// ❌ 誤ったインデックス:RangeがSortより前
db.orders.createIndex({ userId: 1, total: 1, status: 1, createdAt: -1 }, { name: 'idx_wrong' });
db.orders.find({ userId: 'user_001', status: 'paid' })
  .sort({ createdAt: -1 }).explain('executionStats');
// SORTステージ発生(メモリソート)、totalKeysExaminedがnReturnedより大幅に大きい

// ✅ 正しいインデックス:ESR順序
db.orders.dropIndex('idx_wrong');
db.orders.createIndex({ userId: 1, status: 1, createdAt: -1, total: 1 }, { name: 'idx_esr' });
db.orders.find({ userId: 'user_001', status: 'paid' })
  .sort({ createdAt: -1 }).explain('executionStats');
// SORTステージなし、totalKeysExamined ≈ nReturned


7. インデックス設計のベストプラクティス

概念説明: インデックス設計は孤立した技術的決定ではなく、クエリパターン、データ特性、ビジネス要件に基づく包括的なトレードオフです。良いインデックス設計はクエリを高速化しますが、悪い設計はスペースを浪費し書き込みを遅くします。

設計原則:

  1. クエリベース設計—まずexplain()とスロークエリログを分析、その後インデックス作成
  2. ESR優先—複合インデックスのフィールド順序はEquality → Sort → Rangeに従う
  3. 高選択性優先—一意値が多いフィールド(userIdなど)は低選択性フィールド(isActiveなど)よりインデックスに適する
  4. インデックスカバレッジ—高頻度クエリのインデックスカバレッジを検討、テーブルルックアップ回避
  5. 定期クリーンアップ$indexStatsで未使用インデックスを発見・削除
100%
graph TB
    A[クエリパターン分析<br/>スロークエリログ] --> B[高頻度クエリを特定]
    B --> C{クエリタイプ?}
    C -->|等価クエリ| D[単一フィールド/一意インデックス]
    C -->|複数条件組み合わせ| E[複合インデックスESR]
    C -->|ソート+フィルタ| F[ESR複合インデックス]
    C -->|少数フィールドのみ表示| G[インデックスカバレッジ]
    B --> H[選択性評価]
    H -->|高選択性| I[✅ インデックス作成]
    H -->|低選択性| J[❌ 作成しない/部分インデックス使用]
    I --> K[作成+検証<br/>explain]
    K --> L[利用率監視<br/>$indexStats]
    L --> M{利用率低い?}
    M -->|はい| N[インデックス削除]
    M -->|いいえ| O[保持]

    style D fill:#d4edda
    style E fill:#d4edda
    style F fill:#d4edda
    style G fill:#d4edda

(1) 推奨アプローチ

JAVASCRIPT
// ✅ 推奨1:単一フィールドインデックスは高頻度クエリをカバー
db.products.createIndex({ sku: 1 });

// ✅ 推奨2:複合インデックスはESR原則に従う
db.orders.createIndex({ userId: 1, status: 1, createdAt: -1 });

// ✅ 推奨3:TTL自動クリーンアップ
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 30 * 86400 });

// ✅ 推奨4:スペース節約インデックス
db.products.createIndex(
  { category: 1 },
  { partialFilterExpression: { isActive: true } }
);

// ✅ 推奨5:一意インデックスでデータ整合性確保
db.users.createIndex({ email: 1 }, { unique: true });

(2) アンチパターン

よくあるアンチパターンとその結果:

アンチパターン 結果 ベストプラクティス
低選択性フィールドのインデックス インデックス効率悪い、オプティマイザが使用しない可能性 部分インデックスまたは複合インデックス使用
インデックス過多(コレクションあたり>10) 書き込みパフォーマンス大幅低下 高頻度クエリのインデックスのみ保持
複合インデックスのフィールド順序誤り インデックス部分無効 ESRルールに従う
不要なインデックス スペース無駄 + 書き込みオーバーヘッド $indexStatsで定期的クリーンアップ
インデックス使用未検証 インデックスが使用されていない可能性 作成後必ずEXPLAINで検証
JAVASCRIPT
// ❌ アンチパターン1:低選択性フィールドのインデックス
db.users.createIndex({ isActive: 1 });
// isActiveはtrue/falseの2値のみ、インデックス効率が低い

// ❌ アンチパターン2:過剰インデックス
// 1つのコレクションに20以上のインデックス、書き込み性能が大幅に低下

// ❌ アンチパターン3:複合インデックスのフィールド順序誤り
db.products.createIndex({ price: 1, category: 1 });
// 誤り:priceはcategoryより後に配置すべき

// ❌ アンチパターン4:不要なインデックス
db.users.createIndex({ lastLoginAt: 1 });
// lastLoginAtでほとんど検索しない場合、インデックスは無駄


8. インデックスパフォーマンス監視

概念説明: インデックス監視は本番環境の運用で不可欠。スロークエリログとインデックス使用統計を分析することで、未使用インデックス(スペース無駄)、非効率インデックス(最適化必要)、欠落インデックス(作成必要)を特定できます。

動作原理: MongoDBの組み込みProfilerがスロークエリをログに記録し、$indexStats集計パイプラインが各インデックスの使用回数とクエリ所要時間を追跡します。これらを組み合わせることでインデックス健全性の包括的なビューを提供。

監視指標:

指標 コマンド 健全値 警告値
インデックス使用率 $indexStats ops > 1,000/日 ops = 0(未使用)
スロークエリ数 system.profile 0 > 10/時間
インデックスサイズ totalIndexSize() データの< 50% データの> 100%
インデックス断片化 collStats 平均充填率 > 80% < 60%
JAVASCRIPT
// === スロークエリ分析 ===
db.setProfilingLevel(2, { slowms: 100 });
// 100ms超のクエリを記録

// === スロークエリ確認 ===
db.system.profile.find({ millis: { $gt: 100 } })
  .sort({ ts: -1 })
  .limit(10);

// === インデックス使用統計確認 ===
db.products.aggregate([
  { $indexStats: {} }
]);
// 未使用インデックスを発見

// === 未使用インデックス削除 ===
db.products.dropIndex('unused_index_name');

要点分析:

  1. Profiling Level 0 = オフ、1 = スロークエリのみ、2 = 全記録(Level 2はパフォーマンスに影響、デバッグ目的のみ)
  2. $indexStatsaccesses.opsが0の場合、MongoDB起動以来一度も使用されていないことを意味
  3. 本番環境推奨:Level 1 + slowms: 100、監視粒度とパフォーマンスのバランス

▶ サンプル:TTLインデックス + 部分インデックス + ESRの実践

JAVASCRIPT
// シナリオ1:TTLインデックスでセッションを自動クリア(30分で期限切れ)
db.sessions.insertMany([
  { userId: 'user_001', token: 'abc', createdAt: new Date() },
  { userId: 'user_002', token: 'xyz', createdAt: new Date(Date.now() - 31 * 60 * 1000) }  // 期限切れ
]);

db.sessions.createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 30 * 60 }  // 30分
);

// 60秒後、期限切れドキュメントが自動削除
// db.sessions.find() → user_001のセッションのみ

// シナリオ2:部分インデックス - 販売中の商品のみインデックス(70%スペース節約)
db.products.createIndex(
  { category: 1, price: 1 },
  {
    partialFilterExpression: {
      isActive: true,
      stock: { $gt: 0 }
    }
  }
);

// クエリにfilter条件を含む場合のみ部分インデックス使用
db.products.find({
  category: 'Electronics',
  isActive: true,    // partialFilterExpressionにマッチ必要
  stock: { $gt: 0 }, // partialFilterExpressionにマッチ必要
  price: { $gte: 100, $lte: 500 }
}).explain();
// winningPlan.inputStage.stage: IXSCAN(部分インデックスが使用された)

// シナリオ3:ESRルールの実践 - 注文照会
db.orders.insertMany([
  { userId: 'user_001', status: 'paid', createdAt: new Date('2026-07-01'), total: 100 },
  { userId: 'user_001', status: 'paid', createdAt: new Date('2026-07-02'), total: 200 },
  { userId: 'user_002', status: 'pending', createdAt: new Date('2026-07-03'), total: 50 }
]);

// ESR最適インデックス:Equality → Sort → Range
db.orders.createIndex({
  userId: 1,        // E - 等価フィルタ
  status: 1,        // E - 等価フィルタ
  createdAt: -1,    // S - ソート(方向マッチング)
  total: 1          // R - 範囲クエリ(最後に配置)
});

// 効率的クエリ:ユーザーの支払い済み注文、日付逆順、価格範囲
db.orders.find({
  userId: 'user_001',                              // E
  status: 'paid',                                  // E
  total: { $gte: 50, $lte: 300 }                   // R
}).sort({ createdAt: -1 }).limit(20)               // S
.explain('executionStats');

// 出力:複合インデックスのみ使用、追加ソート不要
// totalKeysExamined: 2, totalDocsExamined: 2, nReturned: 2

出力: TTLは期限切れセッションを自動クリーンアップ、部分インデックスはスペースを節約、ESR複合インデックスはクエリパフォーマンスを最適化。

❓ よくある質問

Q TTLインデックスのドキュメント削除の遅延は?
A バックグラウンドスレッドは60秒ごとにインデックスをスキャン。最大遅延は60秒+ドキュメントの寿命。
Q 部分インデックス vs スパースインデックス?
A 部分インデックスはより複雑な条件($gt/$gte/$and)をサポート、スパースインデックスはフィールド存在のみベース。部分インデックス推奨(より柔軟)。
Q ESRルールのソートフィールド方向は?
A ソート方向はインデックス方向にマッチする必要がある。sort({ createdAt: -1 })createdAt: -1インデックスを使用。
Q インデックスはいつ削除される?
A (1)手動でdropIndex;(2)コレクション削除;(3)TTLインデックス自動期限切れ(日付フィールドのみ)。

📖 まとめ


📝 練習問題

  1. 基本問題(⭐)usersコレクションのemailカラムに一意インデックスを作成。
  2. 基本問題(⭐)sessionsコレクションにTTLインデックスを作成(30分で期限切れ)。
  3. 応用問題(⭐⭐)productsコレクションに部分インデックスを作成(販売中の商品のみ)。
  4. 応用問題(⭐⭐)ordersコレクションにESRルールを使った最適インデックスを設計。
  5. チャレンジ問題(⭐⭐⭐):完全なECインデックススキーム(10+インデックス)を設計し、$indexStatsで使用状況を分析、未使用インデックスを削除。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%