Docs Menu
Docs Home
/
MongoDB マニュアル
/ / /

TTL を設定してコレクションのデータを期限切れにする

項目一覧

  • MongoDB Atlas UI でのドキュメントの期限切れ
  • 指定した秒数後にドキュメントを期限切れにする
  • フィルター条件でドキュメントメントを期限切れにする
  • 特定のクロック時間後にドキュメントを期限切れにする
  • NaN を使用して設定されたインデックス

このドキュメントでは、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) 機能によってコレクションからドキュメントが削除されることはありません。

Atlas の UI でデータを期限切れにするには、次の手順を行います。

1
  1. まだ表示されていない場合は、目的のプロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。

  2. まだ表示されていない場合は、ナビゲーション バーのProjectsメニューからプロジェクトを選択します。

  3. Clusters ページがまだ表示されていない場合は、サイドバーの Database をクリックします。

    [ Clusters (クラスター) ] ページが表示されます。

2
  1. 期限切れにするデータが含まれているクラスターについては、 Browse Collectionsをクリックします。

  2. 左のナビゲーション ペインでデータベースをクリックします。

  3. 左のナビゲーション ペインでコレクションをクリックします。

3
  1. [Indexes] タブをクリックします。

  2. [Create Index] をクリックします。

4
  1. Fields セクションで、インデックス キー仕様ドキュメントを入力します。この例では、次のテキストを入力して、 expiresAfter フィールドにインデックスを作成します。

    { "expiresAfter": 1 }
  2. Options セクションに expireAfterSeconds オプションを入力する。この例では、 expiresAfter フィールドの値の 1 秒後にデータを期限切れにするには、次のテキストを入力します。

    { expireAfterSeconds: 1 }
  3. [Review] をクリックします。

  4. [Confirm] をクリックします。

5
  1. 左のナビゲーション ペインで、インデックスを含むコレクションをクリックします。

  2. [Find] タブをクリックします。

  3. [Insert Document] をクリックします。

  4. _id フィールドの下のテキスト フィールドをクリックし、フィールド名 expiresAfter を入力します。

  5. expiresAfter の横にあるテキスト フィールドをクリックし、次の値を入力します。

    2023-10-01T12:00:00.000+00:00

    この値は2023 年 10 月 1 日 12:00 以降、データが期限切れになります。

  6. データ型ドロップダウン メニューをクリックし、データ型の値を Date に変更します。

  7. [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]12フィールドに 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 値でデータが期限切れになります。

警告

データ損失の可能性

TTL インデックスの expireAfterSecondsNaN に設定されている場合、アップグレード、ダウングレード、および特定の同期操作によって予期しない動作が発生し、データが失われる可能性があります。

TTL インデックス構成で expireAfterSecondsNaN に設定しないでください。

MongoDB 5.0 以前のバージョンでは、TTL インデックスの expireAfterSecondsNaN に設定されている場合、MongoDB はログにエラーを記録し、レコードを削除しません。

MongoDB 5.0.0 - 5.0.13 (および 6.0.0 - 6.0.1) 以降、NaN0 として扱われます。TTL インデックスが expireAfterSecondsNaN に設定して構成されている場合、すべての TTL インデックス付きドキュメントは直ちに期限切れになります。

MongoDB 5.0.14 (および 6.0.2) 以降では、サーバーは expireAfterSecondsNaN に設定されている 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 インデックスを削除するか修正してください。

1

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();
2

スクリプトが検出した、誤って構成されたexpireAfterSeconds値をアップデートするには、collMod コマンドを使用します。

別の方法として、誤って構成された TTL インデックスを dropし、その後 createIndexes コマンドを使用して再作成することもできます。

戻る

TTL Indexes