コレクション TTL の設定
Zilliz Cloud は、Time-to-Live (TTL) ポリシーを使用してエンティティを自動的に期限切れにすることができます。期限切れのエンティティは、クエリおよび検索結果に即座に表示されなくなり、次のコンパクションサイクルでストレージから物理的に削除されます — 通常は 24 時間以内です。
TTL には 2 つのモードがあります:
-
コレクション レベル TTL — すべてのエンティティで共有される 1 つの保持期間ウィンドウ。
collection.ttl.secondsプロパティを使用して設定します。 -
エンティティ レベル TTL — 各エンティティが専用の
TIMESTAMPTZフィールドに独自の絶対有効期限を持ち、ttl_fieldプロパティを通じて TTL フィールドとして指定されます。
この機能はマネージド コレクションにのみ適用されます。
制限
-
2 つの TTL モードは相互に排他的です。コレクションに
collection.ttl.secondsとttl_fieldを同時に設定することはできません。切り替える方法については、2 つのモード間の移行 を参照してください。 -
コレクション レベル TTL は、コレクション全体に 1 つのウィンドウを適用します。単一の行に異なる有効期間が必要な場合は、エンティティ レベル TTL を使用してください。
-
エンティティ レベル TTL のフィールドは
TIMESTAMPTZである必要があります。他の型は拒否されます。 -
コレクションあたり 1 つの TTL フィールドです。スキーマに複数の
TIMESTAMPTZフィールドを含めることはできますが、ttl_fieldで指定できるのは 1 つだけです。 -
ttl_fieldを削除しても、期限切れのエンティティは復活しません。期限切れのエンティティを復元するには、NULLまたは将来の有効期限タイムスタンプでアップサートしてください。
概要
展開
TTL を使用するタイミング
TTL は、保持が ポリシー である場合に適切なツールです — 特定のエンティティが最終的に削除されるべきであることを事前に把握しており、クラスターにそれを強制させたい場合に、cron ジョブを書くことなく実現できます。
典型的なシナリオ:
-
時間枠付きデータセット。 ログ、メトリクス、イベント、または短命なフィーチャー キャッシュの最後の N 日間のみを保持します。
-
マルチテナント コレクション。 同じコレクション内で異なるテナントが異なる保持期間ウィンドウを持ちます。
-
レコードごとの保持ポリシー。 IoT パイプライン、ドキュメント ストア、または MLOps フィーチャー ストアでのドキュメントごとの有効期間。
-
ホット / コールド データの混在。 短命なエンティティが、同じコレクション内の長期的なエンティティと共存します。
-
コンプライアンス主導の有効期限。 GDPR スタイルのデータ最小化で、各レコードが独自の「削除期限日」を持ちます。
-
ビジネス時間ベースの有効期限。 エンティティが、特定の絶対的な時点(キャンペーン終了、セッション期限切れ)までのみ有効なレコードを表します。
期限切れのエンティティは、検索またはクエリ結果に表示されません。ただし、次のデータコンパクションが実行されるまでストレージに残る場合があります。これは通常、次の 24 時間以内に実施されます。
TTL モード
2 つのモードは、異なる保持に関する質問に答えます:
-
コレクション レベル TTL は、すべてのエンティティに単一の保持期間を適用します。各エンティティは
insert_ts + ttl_secondsで期限切れになります。 -
エンティティ レベル TTL は、各エンティティが独自の絶対有効期限を
TIMESTAMPTZフィールドに保存できるようにします。そのフィールドのNULLは、エンティティが期限切れにならないことを意味します。
コレクションは一度に 1 つ のモードを使用します — 2 つは相互に排他的です。モード間の切り替えは複数ステップの操作です。2 つのモード間の移行を参照してください。
モードの選択にはこの表を使用してください:
状況が次の場合… | 使用するもの |
|---|---|
コレクション内のすべてのエンティティが同じ保持期間ウィンドウに従うべき場合 | コレクション レベル TTL |
保持が「挿入時点から N 秒間保持する」場合 | コレクション レベル TTL |
同じコレクション内で異なるエンティティに異なる有効期間が必要な場合(テナントごと、ホット/コールド、ドキュメントごと) | エンティティ レベル TTL |
保持が絶対的な壁時刻の場合(例: 2027-01-01T00:00:00Z) | エンティティ レベル TTL |
保持が挿入タイムスタンプではなくビジネスタイムスタンプによって決まる場合 | エンティティ レベル TTL |
挿入後にエンティティの有効期間を更新または延長したい場合 | エンティティ レベル TTL |
一部のエンティティは期限切れにならず、他のエンティティは期限切れになるべき場合 | エンティティ レベル TTL(期限切れにならないものには NULL を使用) |
コレクション レベル TTL の設定
コレクション内のすべてのエンティティが同じ保持期間ウィンドウに従うべき場合に、コレクション レベル TTL を使用します。
新規コレクションでの有効化
作成時に properties マップを通じて collection.ttl.seconds(整数、秒単位)を渡します。
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True, auto_id=False)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=128)
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector", index_type="AUTOINDEX", metric_type="COSINE"
)
client.create_collection(
collection_name="my_collection",
schema=schema,
index_params=index_params,
properties={
"collection.ttl.seconds": 1209600 # 14 days
},
)
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder().build();
schema.addField(AddFieldReq.builder().fieldName("id").dataType(DataType.Int64)
.isPrimaryKey(true).autoID(false).build());
schema.addField(AddFieldReq.builder().fieldName("vector").dataType(DataType.FloatVector)
.dimension(128).build());
IndexParam indexParam = IndexParam.builder().fieldName("vector")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.COSINE).build();
Map<String, String> properties = new HashMap<>();
properties.put("collection.ttl.seconds", "1209600"); // 14 days
client.createCollection(CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.indexParams(Collections.singletonList(indexParam))
.properties(properties)
.build());
const { MilvusClient, DataType } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
await client.createCollection({
collection_name: "my_collection",
fields: [
{ name: "id", data_type: DataType.Int64, is_primary_key: true, autoID: false },
{ name: "vector", data_type: DataType.FloatVector, dim: 128 },
],
index_params: [
{ field_name: "vector", index_type: "AUTOINDEX", metric_type: "COSINE" },
],
properties: {
"collection.ttl.seconds": 1209600, // 14 days
},
});
err = client.CreateCollection(ctx, milvusclient.NewCreateCollectionOption("my_collection", schema).
WithProperty(common.CollectionTTLConfigKey, 1209600)) // TTL in seconds
if err != nil {
fmt.Println(err.Error())
// handle error
}
export params='{
"ttlSeconds": 1209600
}'
export CLUSTER_ENDPOINT="YOUR_CLUSTER_ENDPOINT"
export TOKEN="YOUR_CLUSTER_TOKEN"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"params\": $params
}"
既存のコレクションで有効にする
properties マップに collection.ttl.seconds を指定して alter_collection_properties を呼び出すことで、すでに使用されているコレクションに TTL を適用できます。
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# Assumes "my_collection" was created earlier without TTL
schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True, auto_id=False)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=128)
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector", index_type="AUTOINDEX", metric_type="COSINE"
)
if not client.has_collection("my_collection"):
client.create_collection(
collection_name="my_collection",
schema=schema,
index_params=index_params,
)
client.alter_collection_properties(
collection_name="my_collection",
properties={"collection.ttl.seconds": 1209600},
)
import java.util.HashMap;
import java.util.Map;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.AlterCollectionPropertiesReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
// Assumes "my_collection" was created earlier without TTL.
Map<String, String> properties = new HashMap<>();
properties.put("collection.ttl.seconds", "1209600");
client.alterCollectionProperties(AlterCollectionPropertiesReq.builder()
.collectionName("my_collection")
.properties(properties)
.build());
const { MilvusClient } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
// Assumes "my_collection" was created earlier without TTL.
await client.alterCollectionProperties({
collection_name: "my_collection",
properties: { "collection.ttl.seconds": 1209600 },
});
err = client.AlterCollectionProperties(ctx, milvusclient.NewAlterCollectionPropertiesOption("my_collection").
WithProperty(common.CollectionTTLConfigKey, 60))
if err != nil {
fmt.Println(err.Error())
// handle error
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/alter_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
\"collectionName\": \"my_collection\",
\"properties\": {
\"collection.ttl.seconds\": 1209600
}
}"
TTL 設定の削除
コレクション内のデータを無期限に保持する場合は、そのコレクションから TTL 設定を単純に削除できます。
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
client.drop_collection_properties(
collection_name="my_collection",
property_keys=["collection.ttl.seconds"],
)
import java.util.Collections;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.DropCollectionPropertiesReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
client.dropCollectionProperties(DropCollectionPropertiesReq.builder()
.collectionName("my_collection")
.propertyKeys(Collections.singletonList("collection.ttl.seconds"))
.build());
const { MilvusClient } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
await client.dropCollectionProperties({
collection_name: "my_collection",
properties: ["collection.ttl.seconds"],
});
err = client.DropCollectionProperties(ctx, milvusclient.NewDropCollectionPropertiesOption("my_collection", common.CollectionTTLConfigKey))
if err != nil {
fmt.Println(err.Error())
// handle error
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/drop_properties" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
\"collectionName\": \"my_collection\",
\"propertyKeys\": [
\"collection.ttl.seconds\"
]
}"
エンティティレベルの TTL の設定
エンティティレベルの TTL を使用すると、各エンティティに固有の絶対有効期限を持たせることができます。この時間は、スキーマで宣言した専用の TIMESTAMPTZ 列に保存され、その列を ttl_field コレクションプロパティを通じて TTL フィールドとしてマークします。
新しいコレクションでの有効化
作成時にエンティティレベルの TTL を有効にするには、同じ create_collection 呼び出し内で 2 つの追加が必要です。スキーマ内の TIMESTAMPTZ フィールドと、そのフィールドを指す ttl_field プロパティです。
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
schema = client.create_schema(enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True, auto_id=False)
schema.add_field("expire_at", DataType.TIMESTAMPTZ, nullable=True)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=128)
index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_type="AUTOINDEX",
metric_type="COSINE")
client.create_collection(
collection_name="my_collection",
schema=schema,
index_params=index_params,
properties={"ttl_field": "expire_at"},
)
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder().build();
schema.addField(AddFieldReq.builder().fieldName("id").dataType(DataType.Int64)
.isPrimaryKey(true).autoID(false).build());
schema.addField(AddFieldReq.builder().fieldName("expire_at").dataType(DataType.Timestamptz)
.isNullable(true).build());
schema.addField(AddFieldReq.builder().fieldName("vector").dataType(DataType.FloatVector)
.dimension(128).build());
IndexParam indexParam = IndexParam.builder().fieldName("vector")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.COSINE).build();
Map<String, String> properties = new HashMap<>();
properties.put("ttl_field", "expire_at");
client.createCollection(CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.indexParams(Collections.singletonList(indexParam))
.properties(properties)
.build());
const { MilvusClient, DataType } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
await client.createCollection({
collection_name: "my_collection",
fields: [
{ name: "id", data_type: DataType.Int64, is_primary_key: true, autoID: false },
{ name: "expire_at", data_type: DataType.Timestamptz, nullable: true },
{ name: "vector", data_type: DataType.FloatVector, dim: 128 },
],
index_params: [
{ field_name: "vector", index_type: "AUTOINDEX", metric_type: "COSINE" },
],
properties: { ttl_field: "expire_at" },
});
// go
# restful
コレクションが作成されたら、ISO 8601 タイムスタンプ文字列を使用してエンティティを挿入します。
- Python
- Java
- NodeJS
- Go
- cURL
import random
from pymilvus import MilvusClient
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# Assumes "my_collection" was created earlier with \`ttl_field\`: "expire_at"
rows = [
# Never expires
{"id": 1, "expire_at": None,
"vector": [random.random() for _ in range(128)]},
# Expires at 2026-12-31 UTC midnight
{"id": 2, "expire_at": "2026-12-31T00:00:00Z",
"vector": [random.random() for _ in range(128)]},
# Shanghai local time — normalized to UTC internally
{"id": 3, "expire_at": "2027-01-01T00:00:00+08:00",
"vector": [random.random() for _ in range(128)]},
]
client.insert("my_collection", rows)
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.google.gson.Gson;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.InsertReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
// Assumes "my_collection" was created earlier with \`ttl_field\`: "expire_at".
Gson gson = new Gson();
Random rng = new Random();
List<Float> vector = new ArrayList<>();
for (int i = 0; i < 128; i++) vector.add(rng.nextFloat());
List<JsonObject> rows = new ArrayList<>();
// Never expires
JsonObject r1 = new JsonObject();
r1.addProperty("id", 1);
r1.add("expire_at", JsonNull.INSTANCE);
r1.add("vector", gson.toJsonTree(vector));
rows.add(r1);
// Expires at 2026-12-31 UTC midnight
JsonObject r2 = new JsonObject();
r2.addProperty("id", 2);
r2.addProperty("expire_at", "2026-12-31T00:00:00Z");
r2.add("vector", gson.toJsonTree(vector));
rows.add(r2);
// Shanghai local time — normalized to UTC internally
JsonObject r3 = new JsonObject();
r3.addProperty("id", 3);
r3.addProperty("expire_at", "2027-01-01T00:00:00+08:00");
r3.add("vector", gson.toJsonTree(vector));
rows.add(r3);
client.insert(InsertReq.builder()
.collectionName("my_collection")
.data(rows)
.build());
const { MilvusClient } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
const vector = Array.from({ length: 128 }, () => Math.random());
// Assumes "my_collection" was created earlier with \`ttl_field\`: "expire_at".
await client.insert({
collection_name: "my_collection",
data: [
// Never expires
{ id: 1, expire_at: null, vector },
// Expires at 2026-12-31 UTC midnight
{ id: 2, expire_at: "2026-12-31T00:00:00Z", vector },
// Shanghai local time — normalized to UTC internally
{ id: 3, expire_at: "2027-01-01T00:00:00+08:00", vector },
],
});
// go
# restful
すべてのクエリおよびベクトル検索において、サーバーが自動的に TTL フィルターを注入します。ユーザー自身がフィルターを記述する必要はなく、有効期限が切れたエンティティは結果に表示されることはありません。
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
client.load_collection("my_collection")
# Expired rows are filtered out automatically
results = client.query(
collection_name="my_collection",
filter="id >= 0",
output_fields=["id", "expire_at"],
limit=10,
)
print(results)
import java.util.Arrays;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.LoadCollectionReq;
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
client.loadCollection(LoadCollectionReq.builder()
.collectionName("my_collection")
.build());
// Expired rows are filtered out automatically
QueryResp results = client.query(QueryReq.builder()
.collectionName("my_collection")
.filter("id >= 0")
.outputFields(Arrays.asList("id", "expire_at"))
.limit(10L)
.build());
System.out.println(results.getQueryResults());
const { MilvusClient } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
await client.loadCollection({ collection_name: "my_collection" });
// Expired rows are filtered out automatically
const results = await client.query({
collection_name: "my_collection",
filter: "id >= 0",
output_fields: ["id", "expire_at"],
limit: 10,
});
console.log(results.data);
// go
# restful
同じ自動フィルタリングは client.search() にも適用されます。
エンティティがコンパクションによって物理的に削除される前にその有効期限を延長するには、より遅い有効期限タイムスタンプ(または None)を使用して upsert を実行し、エンティティをクエリ可能なセットに戻します。
- Python
- Java
- NodeJS
- Go
- cURL
import random
from pymilvus import MilvusClient
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
client.upsert("my_collection", [
{"id": 2,
"vector": [random.random() for _ in range(128)],
"expire_at": "2028-01-01T00:00:00Z"},
])
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.UpsertReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
Gson gson = new Gson();
Random rng = new Random();
List<Float> vector = new ArrayList<>();
for (int i = 0; i < 128; i++) vector.add(rng.nextFloat());
JsonObject row = new JsonObject();
row.addProperty("id", 2);
row.add("vector", gson.toJsonTree(vector));
row.addProperty("expire_at", "2028-01-01T00:00:00Z");
client.upsert(UpsertReq.builder()
.collectionName("my_collection")
.data(Collections.singletonList(row))
.build());
const { MilvusClient } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
const vector = Array.from({ length: 128 }, () => Math.random());
await client.upsert({
collection_name: "my_collection",
data: [
{ id: 2, vector, expire_at: "2028-01-01T00:00:00Z" },
],
});
// go
# restful
既存のコレクションで有効にする
コレクションが既に存在し、collection.ttl.seconds が設定されていない場合、add_collection_field を使用して TIMESTAMPTZ カラムを追加し、その後 alter_collection_properties を使用してそれを TTL フィールドとしてマークします。オプションで、履歴行をアップサートして期限切れタイムスタンプをバックフィルできます。バックフィルしない行は NULL のままとなり、期限切れになりません。
- Python
- Java
- NodeJS
- Go
- cURL
import random
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# Step 1 — add a TIMESTAMPTZ column to the schema
client.add_collection_field(
collection_name="my_collection",
field_name="expire_at",
data_type=DataType.TIMESTAMPTZ,
nullable=True,
)
# Step 2 — mark the new column as the TTL field
client.alter_collection_properties(
collection_name="my_collection",
properties={"ttl_field": "expire_at"},
)
# Step 3 (optional) — backfill expiration timestamps for historical rows
client.upsert("my_collection", [
{"id": 1,
"vector": [random.random() for _ in range(128)],
"expire_at": "2026-12-31T00:00:00Z"},
])
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddCollectionFieldReq;
import io.milvus.v2.service.collection.request.AlterCollectionPropertiesReq;
import io.milvus.v2.service.vector.request.UpsertReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
// Step 1 — add a TIMESTAMPTZ column to the schema
client.addCollectionField(AddCollectionFieldReq.builder()
.collectionName("my_collection")
.fieldName("expire_at")
.dataType(DataType.Timestamptz)
.isNullable(true)
.build());
// Step 2 — mark the new column as the TTL field
Map<String, String> properties = new HashMap<>();
properties.put("ttl_field", "expire_at");
client.alterCollectionProperties(AlterCollectionPropertiesReq.builder()
.collectionName("my_collection")
.properties(properties)
.build());
// Step 3 (optional) — backfill expiration timestamps for historical rows
Gson gson = new Gson();
Random rng = new Random();
List<Float> vector = new ArrayList<>();
for (int i = 0; i < 128; i++) vector.add(rng.nextFloat());
JsonObject row = new JsonObject();
row.addProperty("id", 1);
row.add("vector", gson.toJsonTree(vector));
row.addProperty("expire_at", "2026-12-31T00:00:00Z");
client.upsert(UpsertReq.builder()
.collectionName("my_collection")
.data(Collections.singletonList(row))
.build());
const { MilvusClient, DataType } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
const vector = Array.from({ length: 128 }, () => Math.random());
// Step 1 — add a TIMESTAMPTZ column to the schema
await client.addCollectionField({
collection_name: "my_collection",
field: { name: "expire_at", data_type: DataType.Timestamptz, nullable: true },
});
// Step 2 — mark the new column as the TTL field
await client.alterCollectionProperties({
collection_name: "my_collection",
properties: { ttl_field: "expire_at" },
});
// Step 3 (optional) — backfill expiration timestamps for historical rows
await client.upsert({
collection_name: "my_collection",
data: [
{ id: 1, vector, expire_at: "2026-12-31T00:00:00Z" },
],
});
// go
# restful
TTL 設定の削除
property_keys に ttl_field を含めて drop_collection_properties を呼び出すと、エンティティごとの有効期限が停止します。TIMESTAMPTZ カラム自体はスキーマに残ったままとなり、通常のフィールドとして引き続きクエリを実行できます。
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
client.drop_collection_properties(
collection_name="my_collection",
property_keys=["ttl_field"],
)
import java.util.Collections;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.DropCollectionPropertiesReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
client.dropCollectionProperties(DropCollectionPropertiesReq.builder()
.collectionName("my_collection")
.propertyKeys(Collections.singletonList("ttl_field"))
.build());
const { MilvusClient } = require("@zilliz/milvus2-sdk-node");
const client = new MilvusClient({ address: "YOUR_CLUSTER_ENDPOINT" });
await client.dropCollectionProperties({
collection_name: "my_collection",
properties: ["ttl_field"],
});
// go
# restful
ttl_field をドロップすると、将来のクエリに対する自動フィルタが無効になりますが、すでに有効期限が切れたエンティティが自動的に再度表示されるわけではありません。以前有効期限が切れたエンティティを表示可能にするには、None または将来の有効期限タイムスタンプを使用してアップサートする必要があります。これが、同じロードセッション内で有効期限切れの行へのアクセスを回復する唯一の方法です。
2 つのモード間での移行Private Preview
2 つの TTL モードは相互に排他的であるため、それらを切り替えるには複数ステップの操作が必要です。
コレクションレベルからエンティティレベルの TTL へ切り替える
コレクションが collection.ttl.seconds で作成されており、エンティティごとの有効期限に切り替えたい場合は、以下の 4 つのステップに従ってください。ステップ 1 を省略すると、ステップ 3 が collection TTL is already set, cannot be set ttl field というエラーで失敗します。
- Python
- Java
- NodeJS
- Go
- cURL
import random
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# Assumes "my_collection" already exists with \`collection.ttl.seconds\` set.
# Step 1 — disable collection-level TTL (mandatory; the two modes are mutually exclusive)
client.drop_collection_properties(
collection_name="my_collection",
property_keys=["collection.ttl.seconds"],
)
# Step 2 — add a TIMESTAMPTZ column to the schema
client.add_collection_field(
collection_name="my_collection",
field_name="expire_at",
data_type=DataType.TIMESTAMPTZ,
nullable=True,
)
# Step 3 — set the ttl_field property on the column you just added
client.alter_collection_properties(
collection_name="my_collection",
properties={"ttl_field": "expire_at"},
)
# Step 4 (optional) — backfill expiration timestamps for historical entities
client.upsert("my_collection", [
{"id": 1,
"vector": [random.random() for _ in range(128)],
"expire_at": "2026-12-31T00:00:00Z"},
])
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddCollectionFieldReq;
import io.milvus.v2.service.collection.request.AlterCollectionPropertiesReq;
import io.milvus.v2.service.collection.request.DropCollectionPropertiesReq;
import io.milvus.v2.service.vector.request.UpsertReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
// Assumes "my_collection" already exists with \`collection.ttl.seconds\` set.
// Step 1 — disable collection-level TTL (mandatory; the two modes are mutually exclusive)
client.dropCollectionProperties(DropCollectionPropertiesReq.builder()
.collectionName("my_collection")
.propertyKeys(Collections.singletonList("collection.ttl.seconds"))
.build());
// Step 2 — add a TIMESTAMPTZ column to the schema
client.addCollectionField(AddCollectionFieldReq.builder()
.collectionName("my_collection")
.fieldName("expire_at")
.dataType(DataType.Timestamptz)
.isNullable(true)
.build());
// Step 3 — set the ttl_field property on the column you just added
Map<String, String> ttlField = new HashMap<>();
ttlField.put("ttl_field", "expire_at");
client.alterCollectionProperties(AlterCollectionPropertiesReq.builder()
.collectionName("my_collection")
.properties(ttlField)
.build());
// Step 4 (optional) — backfill expiration timestamps for historical entities
Gson gson = new Gson();
Random rng = new Random();
List<Float> vector = new ArrayList<>();
for (int i = 0; i < 128; i++) vector.add(rng.nextFloat());
JsonObject row = new JsonObject();
row.addProperty("id", 1);
row.add("vector", gson.toJsonTree(vector));
row.addProperty("expire_at", "2026-12-31T00:00:00Z");
client.upsert(UpsertReq.builder()
.collectionName("my_collection")
.data(Collections.singletonList(row))
.build());
// nodejs
// go
# restful
expire_at をバックフィルしない履歴エンティティは、その列に NULL が設定され、期限が無期限であることを意味します。有限のライフタイムを持つべき行のみをバックフィルしてください。
エンティティレベルの TTL からコレクションレベルの TTL への切り替え
逆方向に移行するには、ttl_field を削除し、collection.ttl.seconds を設定します:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import MilvusClient
client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")
# Assumes "my_collection" already exists with \`ttl_field\` set.
client.drop_collection_properties(
collection_name="my_collection",
property_keys=["ttl_field"],
)
client.alter_collection_properties(
collection_name="my_collection",
properties={"collection.ttl.seconds": 1209600}, # 14 days
)
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.AlterCollectionPropertiesReq;
import io.milvus.v2.service.collection.request.DropCollectionPropertiesReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("YOUR_CLUSTER_ENDPOINT")
.build());
// Assumes "my_collection" already exists with \`ttl_field\` set.
client.dropCollectionProperties(DropCollectionPropertiesReq.builder()
.collectionName("my_collection")
.propertyKeys(Collections.singletonList("ttl_field"))
.build());
Map<String, String> properties = new HashMap<>();
properties.put("collection.ttl.seconds", "1209600"); // 14 days
client.alterCollectionProperties(AlterCollectionPropertiesReq.builder()
.collectionName("my_collection")
.properties(properties)
.build());
// nodejs
// go
# restful
よくある質問
TTL設定によりデータはいつ期限切れになりますか?
現在、データは挿入またはアップサートされた時点に基づいて期限切れになります。期限切れのデータは検索結果に表示されません。詳細については、例 を参照してください。
期限切れのデータはいつ物理的に削除されますか?
データが期限切れになると、検索結果に含まれなくなります。ただし、物理的な削除は、クラスターのコンパクション ポリシーに従って、後続のシステム コンパクションが実行された後にのみ行われます。
期限切れ後すぐにデータを削除する必要がある場合は、お問い合わせ ください。
CU容量はいつ減少しますか?
クラスターのCU容量は、メモリ使用量とストレージ使用量のいずれか大きい方となります。ストレージ使用量が適用される場合、期限切れのデータが物理的に削除された後、Zilliz Cloud コンソールでCU容量の減少を確認できます。