MongoDBでは古いドキュメントを自動削除する機能として、キャップ付きコレクション(Capped Collections)とTTLインデックス(TTL Indexes)という二つの方法がある。
TTLインデックス(TTL Indexes)
ドキュメントのあるdate型の値に、期間を指定してTTLインデックスを張ると、そのdateの値が指定期間よりも古くなった場合に自動的に削除する。
詳細
- date型のデータがないと使えない
- 1分間隔で削除する(それより細かい間隔では削除できない)
- 複合インデックスでは使えない
- 削除はremoveクエリが発行される。そのため、指定期間通りにドキュメント消える事が保証される訳ではない。removeクエリが流れきるまではドキュメントは残る
- 普通のインデックスと同様に検索クエリのときに使える
キャップ付きコレクション(Capped Collections)
あるサイズを指定してコレクションを作ると、そのサイズ以上にドキュメントが挿入された場合に、古いドキュメントを自動的に削除する。
詳細
- 中のドキュメントを削除できない
- 中のドキュメントサイズが大きくなる更新はできない
- シャーディング対象にできない
- アグリゲーションの
$out
にキャップ付きコレクションは指定できない。 - インデックスがなくても書き込みが早い
もっと細かい話
キャップ付きコレクションでは、書き込み順が、物理的に連続した領域に行われる(事が保証される)。そのため、ドキュメントの物理的な再配置が起こるのような更新はできない。削除できないのも同じ理由。
レプリカ環境だと特に注意が必要で、以下のような状況だとエラーになる。
キャップ付きコレクションをレプリケーションしていて、プライマリでドキュメントを小さくすると、プライマリのディスクには物理的には隙間ができる。しかし、それがセカンダリに伝わると、セカンダリ側では最初から小さい物理領域しか確保されない。その後、プライマリのドキュメントを大きくすると、プライマリ側では隙間が埋まるだけだが、セカンダリではその隙間はないため、エラーになる。
比較
キャップ付きコレクション | TTLインデックス | |
---|---|---|
期間の固定 | × | ○ |
サイズの固定 | ○ | × |
中のドキュメントの削除 | × | ○ |
中のドキュメントの更新 | △ | ○ |
シャーディング対応 | × | ○ |
ドキュメントへの制約 | ○無し | △date型必須 |
書き込み性能 | ○ | △Index更新が必要 |
削除時の負荷 | ○ | △remove実行 |
途中での変更 | △やや難 | ○容易 |
全然別物ですねw