Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

MongoDBで古いドキュメントを自動削除する二つの方法

More than 5 years have passed since last update.

MongoDBでは古いドキュメントを自動削除する機能として、キャップ付きコレクション(Capped Collections)とTTLインデックス(TTL Indexes)という二つの方法がある。

TTLインデックス(TTL Indexes)

http://docs.mongodb.org/manual/core/index-ttl/

ドキュメントのあるdate型の値に、期間を指定してTTLインデックスを張ると、そのdateの値が指定期間よりも古くなった場合に自動的に削除する。

詳細
* date型のデータがないと使えない
* 1分間隔で削除する(それより細かい間隔では削除できない)
* 複合インデックスでは使えない
* 削除はremoveクエリが発行される。そのため、指定期間通りにドキュメント消える事が保証される訳ではない。removeクエリが流れきるまではドキュメントは残る
* 普通のインデックスと同様に検索クエリのときに使える

キャップ付きコレクション(Capped Collections)

http://docs.mongodb.org/manual/core/capped-collections/

あるサイズを指定してコレクションを作ると、そのサイズ以上にドキュメントが挿入された場合に、古いドキュメントを自動的に削除する。

詳細
* 中のドキュメントを削除できない
* 中のドキュメントサイズが大きくなる更新はできない
* シャーディング対象にできない
* アグリゲーションの$outにキャップ付きコレクションは指定できない。
* インデックスがなくても書き込みが早い

もっと細かい話

キャップ付きコレクションでは、書き込み順が、物理的に連続した領域に行われる(事が保証される)。そのため、ドキュメントの物理的な再配置が起こるのような更新はできない。削除できないのも同じ理由。
レプリカ環境だと特に注意が必要で、以下のような状況だとエラーになる。
キャップ付きコレクションをレプリケーションしていて、プライマリでドキュメントを小さくすると、プライマリのディスクには物理的には隙間ができる。しかし、それがセカンダリに伝わると、セカンダリ側では最初から小さい物理領域しか確保されない。その後、プライマリのドキュメントを大きくすると、プライマリ側では隙間が埋まるだけだが、セカンダリではその隙間はないため、エラーになる。

比較

キャップ付きコレクション TTLインデックス
期間の固定 ×
サイズの固定 ×
中のドキュメントの削除 ×
中のドキュメントの更新
シャーディング対応 ×
ドキュメントへの制約 ○無し △date型必須
書き込み性能 △Index更新が必要
削除時の負荷 △remove実行
途中での変更 △やや難 ○容易

全然別物ですねw

fetaro
データエンジニア
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away