TTL を設定してコレクションのデータを期限切れにする
項目一覧
このドキュメントでは、MongoDB の "time to live" つまり TTL コレクション機能について紹介します。TTL コレクションを使用すると、MongoDB にデータを格納し、指定した秒数または特定のクロック時間後に mongod
でデータを自動的に削除することができます。
次の環境でホストされている配置のデータを期限切れにすることができます。
MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン
MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン
データの期限切れは、機械が生成したイベントデータ、ログ、セッション情報など、限られた期間だけ保持すれば良い情報のクラスに活用できます。
特別な TTL インデックス プロパティは、TTL コレクションの実装をサポートします。TTL 機能は、インデックス内の Date 型の値を読み取り、コレクションから期限切れのドキュメントを削除する mongod
のバックグラウンド スレッドに依存しています。
TTL インデックスを作成するには、createIndex()
を使用します。Date 型または Date 型の値を含む配列のインデックス フィールドを指定します。expireAfterSeconds
オプションを使って TTL 値を秒単位で指定します。
注意
TTL インデックスは単一フィールド インデックスです。複合インデックスは TTL プロパティをサポートしていません。TTL インデックスの詳細については、「TTL インデックス」を参照してください。
collMod
コマンドを使用して、既存の TTL インデックスの expireAfterSeconds
を変更できます。
1970-01-01T00:00:00.000Z
の前または 2038-01-19T03:14:07.000Z
の後に timeField
タイムスタンプがあるドキュメントが時系列コレクションに含まれる場合、TTL(time to live) 機能によってコレクションからドキュメントが削除されることはありません。
MongoDB Atlas UI でのドキュメントの期限切れ
Atlas の UI でデータを期限切れにするには、次の手順を行います。
MongoDB Atlas UI で、プロジェクトの Clusters ページに移動します。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
まだ表示されていない場合は、サイドバーの [Clusters] をクリックします。
[ Clusters (クラスター) ] ページが表示されます。
expiresAfterSeconds
オプションを使用してインデックスを作成します
Fields セクションで、インデックス キー仕様ドキュメントを入力します。この例では、次のテキストを入力して、
expiresAfter
フィールドにインデックスを作成します。{ "expiresAfter": 1 } Options セクションに
expireAfterSeconds
オプションを入力する。この例では、expiresAfter
フィールドの値の 1 秒後にデータを期限切れにするには、次のテキストを入力します。{ expireAfterSeconds: 1 } [Review] をクリックします。
[Confirm] をクリックします。
expiresAfter
フィールドを含むドキュメントをコレクションに追加します
左のナビゲーション ペインで、インデックスを含むコレクションをクリックします。
[Find] タブをクリックします。
[Insert Document] をクリックします。
_id フィールドの下のテキスト フィールドをクリックし、フィールド名
expiresAfter
を入力します。expiresAfter
の横にあるテキスト フィールドをクリックし、次の値を入力します。2023-10-01T12:00:00.000+00:00 この値は2023 年 10 月 1 日 12:00 以降、データが期限切れになります。
データ型ドロップダウン メニューをクリックし、データ型の値を Date に変更します。
[Insert] をクリックします。
ドキュメントは、
expiredAfter
フィールドの値の 1 秒後に自動的に期限切れになります。TTL インデックスでは、ドキュメントの期限が切れるまでに 1 ~ 2 秒かかる場合があります。MongoDB Atlas が期限切れのドキュメントを削除することを確認するために、UI を更新する必要がある場合があります。
指定した秒数後にドキュメントを期限切れにする
ターミナルで指定した秒数後にデータを期限切れにすることができます。インデックス フィールドで指定した秒数が経過した後にデータを期限切れにするには、BSON Date 型の値または BSON Date 型オブジェクトの配列を保持するフィールドに TTL インデックスを作成し、 expireAfterSeconds
フィールドにゼロ以外の正の値を指定します。ドキュメントは、インデックス フィールドで指定された時間から expireAfterSeconds
フィールドの秒数が経過すると期限切れになります。[1]
TTLインデックスの expireAfterSeconds
値は、0
から 2147483647
の範囲内(両端を含む)である必要があります。
たとえば、次の操作では、 log_events
コレクションの createdAt
フィールドにインデックスを作成し、 expireAfterSeconds
値で 10
を指定すると、 createdAt
で指定した時刻の 10 秒後が有効期限として設定されます。
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 10 } )
log_events
コレクションにドキュメントを追加するときは、 createdAt
フィールドを現在の時刻に設定します。
db.log_events.insertOne( { "createdAt": new Date(), "logEvent": 2, "logMessage": "Success!" } )
MongoDBは、ドキュメントの createdAt
値 [1] がexpireAfterSeconds
で指定された秒数よりも古くなると、 log_events
コレクションからドキュメントを自動的に削除します。
[1] | (1 、 2)フィールドに BSON Date 型オブジェクトの配列が含まれている場合、少なくとも 1 つの BSON Date 型オブジェクトが expireAfterSeconds で指定された秒数よりも古いと、データは期限切れになります。 |
フィルター条件でドキュメントメントを期限切れにする
特定のフィルター式を使用してドキュメントを期限切れにするには、部分インデックスと TTL インデックスの両方のインデックスを作成します。
パーシャル TTL インデックスの作成
db.foo.createIndex( { F: 1 }, { name: "Partial-TTL-Index", partialFilterExpression: { D : 1 }, expireAfterSeconds: 10 } )
2 つのドキュメントを挿入します。いずれか 1 つは partialFilterExpression
のフィルター式 { D : 1 }
と一致します。
db.foo.insertMany( [ { "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 3}, { "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 1} ] )
10 秒待ってから foo
コレクションをクエリします。
db.foo.find({}, {_id: 0, F: 1, D: 1})
{ D : 1 }
の partialFilterExpression
に一致するドキュメントは削除されています (期限切れ)。その結果、 foo
コレクションには 1 つのドキュメントのみが残ります。
{ "F" : ISODate("2019-03-07T20:59:18.428Z"), "D" : 3}
特定のクロック時間後にドキュメントを期限切れにする
ターミナルで指定した時刻にデータを期限切れにすることができます。特定の時刻にドキュメントを期限切れにするには、まず、BSON Date 型または BSON Date 型オブジェクトの配列の値を保持するフィールドに TTL インデックスを作成し、expireAfterSeconds
値として 0
を指定します。コレクション内の各ドキュメントについて、インデックス付き日付フィールドに、ドキュメントの期限が切れる時間に対応する値を設定します。インデックス付きの日付フィールドに過去の日付が含まれている場合、MongoDB はドキュメントを期限切れと見なします。
たとえば、次の操作は log_events
コレクションの expireAt
フィールドにインデックスを作成し、 expireAfterSeconds
値を 0
に指定します。
db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
各ドキュメントについて、ドキュメントが期限切れになる時間に対応するように expireAt
の値を設定します。たとえば、次のinsertOne()
操作は、 July 22, 2013 14:00:00
に期限切れとなるドキュメントを追加します。
db.log_events.insertOne( { "expireAt": new Date('July 22, 2013 14:00:00'), "logEvent": 2, "logMessage": "Success!" } )
MongoDB は、ドキュメントの expireAt
値が expireAfterSeconds
で指定された秒数よりも古い場合、つまりここでは 0
秒古い場合、log_events
コレクションからドキュメントを自動的に削除します。そのため、指定された expireAt
値でデータが期限切れになります。
NaN を使用して設定されたインデックス
警告
データ損失の可能性
TTL インデックスの expireAfterSeconds
が NaN
に設定されている場合、アップグレード、ダウングレード、および特定の同期操作によって予期しない動作が発生し、データが失われる可能性があります。
TTL インデックス構成で expireAfterSeconds
を NaN
に設定しないでください。
MongoDB 5.0 以前のバージョンでは、TTL インデックスの expireAfterSeconds
が NaN
に設定されている場合、MongoDB はログにエラーを記録し、レコードを削除しません。
MongoDB 5.0.0 - 5.0.13 (および 6.0.0 - 6.0.1) 以降、NaN
は 0
として扱われます。TTL インデックスが expireAfterSeconds
を NaN
に設定して構成されている場合、すべての TTL インデックス付きドキュメントは直ちに期限切れになります。
MongoDB 5.0.14 (および 6.0.2) 以降では、サーバーは expireAfterSeconds
が NaN
に設定されている TTL インデックスを使用しません。
ただし、予期しない動作が発生しうる状況は依然としてあります。次の場合、ドキュメントが期限切れとなる場合があります。
MongoDB 5.0.0 - 5.0.13(または 6.0.0 - 6.0.1)より前のバージョンへの最初の同期中。
以前のバージョンから MongoDB 5.0.0 - 5.0.13 にアップグレードする場合。
5.0より前からコレクションを復元する場合
mongodump
を MongoDB 5.0.0 - 5に変換します。 0 。 13 (または6 . 0 . 0 - 6 。 0 。 1 ) インスタンス。
問題を回避するには、誤って構成された TTL インデックスを削除するか修正してください。
誤って構成されたインデックスの特定
mongosh
shell で次のスクリプトを実行します。 スクリプトはレガシーのmongo
shell では動作しません。
function getNaNIndexes() { const nan_index = []; const dbs = db.adminCommand({ listDatabases: 1 }).databases; dbs.forEach((d) => { if (d.name != 'local') { const listCollCursor = db .getSiblingDB(d.name) .runCommand({ listCollections: 1 }).cursor; const collDetails = { db: listCollCursor.ns.split(".$cmd")[0], colls: listCollCursor.firstBatch.map((c) => c.name), }; collDetails.colls.forEach((c) => db .getSiblingDB(collDetails.db) .getCollection(c) .getIndexes() .forEach((entry) => { if (Object.is(entry.expireAfterSeconds, NaN)) { nan_index.push({ ns: `${collDetails.db}.${c}`, index: entry }); } }) ); } }); return nan_index; }; getNaNIndexes();
誤って構成されたインデックスの修正
スクリプトが検出した、誤って構成されたexpireAfterSeconds
値をアップデートするには、collMod
コマンドを使用します。
別の方法として、誤って構成された TTL インデックスを drop
し、その後 createIndexes
コマンドを使用して再作成することもできます。