TIMESTAMPTZ フィールド
eコマースシステム、コラボレーションツール、分散ログのように、地域をまたいで時間を追跡するアプリケーションでは、タイムゾーン付きタイムスタンプを正確に扱う必要があります。Zilliz Cloud の TIMESTAMPTZ データ型は、関連付けられたタイムゾーンとともにタイムスタンプを保存することで、この機能を提供します。
TIMESTAMPTZ フィールドとは何ですか?
TIMESTAMPTZ フィールドは、タイムゾーンを認識する入力を処理し、すべての時点を内部的に UTC 絶対時刻として保存する、Zilliz Cloud のスキーマ定義済みデータ型 (DataType.TIMESTAMPTZ) です。
-
受け入れ可能な入力形式:
TIMESTAMPTZフィールドは、以下を含む ISO 8601 互換のタイムスタンプ文字列を受け入れます。-
"2024-12-31 22:00:00" -
"2024-12-31T22:00:00" -
"2024-12-31T22:00:00+08:00" -
"2024-12-31T22:00:00Z"
-
-
タイムスタンプの解析ルール: タイムスタンプがどのように解釈されるかは、入力文字列にタイムゾーンが明示されているかどうかによって異なります。
-
入力にタイムゾーンオフセット(たとえば +08:00 または Z)が含まれている場合、それは絶対的な時点として扱われます。
-
入力にタイムゾーンオフセットが含まれていない場合、それはコレクションに設定されたタイムゾーンを使って解釈されます。たとえば、コレクションのタイムゾーンが Asia/Shanghai の場合:
-
"2024-12-31 22:00:00"は 2024-12-31T22:00:00+08:00 として解釈されます -
"2024-12-31T22:00:00"は 2024-12-31T22:00:00Z として解釈され、これは 2025-01-01T06:00:00+08:00 に対応します
-
-
-
内部保存: すべての
TIMESTAMPTZ値は正規化され、協定世界時 (UTC) で保存されます。 -
比較とフィルタリング: TIMESTAMPTZ フィールドに対するすべての比較、フィルタリング、順序付け操作は UTC に正規化された値に対して実行されるため、異なるタイムゾーン間でも一貫した動作が保証されます。
-
TIMESTAMPTZフィールドでは、欠損値を許可するためにnullable=Trueを設定できます。 -
ISO 8601 形式で
default_value属性を使用してデフォルトのタイムスタンプ値を指定できます。
詳細については、Nullable & Default を参照してください。
基本操作
TIMESTAMPTZ フィールドを使用する基本的なワークフローは、Zilliz Cloud の他のスカラーフィールドと同様です: フィールドを定義 → データを挿入 → クエリ/フィルタ。
ステップ 1: TIMESTAMPTZ フィールドを定義する
TIMESTAMPTZ フィールドを使用するには、コレクションを作成するときにコレクションスキーマで明示的に定義します。次の例は、DataType.TIMESTAMPTZ 型の tsz フィールドを持つコレクションを作成する方法を示しています。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
import time
from pymilvus import MilvusClient, DataType
import datetime
import pytz
server_address = "YOUR_CLUSTER_ENDPOINT"
collection_name = "timestamptz_test123"
client = MilvusClient(uri=server_address)
if client.has_collection(collection_name):
client.drop_collection(collection_name)
schema = client.create_schema()
# Add a primary key field
schema.add_field("id", DataType.INT64, is_primary=True)
# Add a TIMESTAMPTZ field that allows null values
schema.add_field("tsz", DataType.TIMESTAMPTZ, nullable=True)
# Add a vector field
schema.add_field("vec", DataType.FLOAT_VECTOR, dim=4)
client.create_collection(collection_name, schema=schema, consistency_level="Session")
print(f"Collection '{collection_name}' with a TimestampTz field created successfully.")
import io.milvus.v2.common.DataType;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
String CLUSTER_ENDPOINT = "YOUR_CLUSTER_ENDPOINT";
String TOKEN = "YOUR_CLUSTER_TOKEN";
// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
.uri(CLUSTER_ENDPOINT)
.token(TOKEN)
.build();
MilvusClientV2 client = new MilvusClientV2(connectConfig);
CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder()
.build();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("tsz")
.dataType(DataType.Timestamptz)
.isNullable(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vec")
.dataType(DataType.FloatVector)
.dimension(4)
.build());
String collectionName = "timestamptz_test123";
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName(collectionName)
.collectionSchema(schema)
.consistencyLevel(ConsistencyLevel.SESSION)
.build();
client.createCollection(requestCreate);
const { MilvusClient, DataType } = require('@zilliz/milvus2-sdk-node');
const serverAddress = 'YOUR_CLUSTER_ENDPOINT';
const collectionName = 'timestamptz_test123';
const client = new MilvusClient({
address: serverAddress,
});
await client.createCollection({
collection_name: collectionName,
fields: [
{
name: 'id',
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: 'tsz',
data_type: DataType.TimestampTZ,
nullable: true,
},
{
name: 'vec',
data_type: DataType.FloatVector,
dim: 4,
},
]
});
// go
curl --request POST \
--url YOUR_CLUSTER_ENDPOINT/v2/vectordb/collections/create \
--header 'Authorization: Bearer YOUR_CLUSTER_TOKEN' \
--header 'Content-Type: application/json' \
--header "Request-Timeout: 10" \
--data '{
"collectionName": "timestamptz_test123",
"schema": {
"autoId": false,
"fields": [
{ "fieldName": "id", "dataType": "Int64", "isPrimary": true },
{ "fieldName": "tsz", "dataType": "Timestamptz", "nullable": true },
{ "fieldName": "vec", "dataType": "FloatVector", "elementTypeParams": { "dim": "4" } }
]
},
"indexParams": [
{
"fieldName": "vec",
"indexName": "vector_index",
"metricType": "L2",
"indexConfig": { "index_type": "AUTOINDEX" }
}
],
"consistencyLevel": "Session"
}'
#include "milvus/MilvusClientV2.h"
auto client = milvus::MilvusClientV2::Create();
milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
milvus::CollectionSchemaPtr schema = std::make_shared<milvus::CollectionSchema>();
schema->AddField({"id", milvus::DataType::INT64, "", true});
schema->AddField(milvus::FieldSchema("tsz", milvus::DataType::TIMESTAMPTZ));
schema->AddField(milvus::FieldSchema("vec", milvus::DataType::FLOAT_VECTOR).WithDimension(4));
const std::string collection_name = "timestamptz_test123";
auto status = client->CreateCollection(milvus::CreateCollectionRequest()
.WithCollectionName(collection_name)
.WithCollectionSchema(schema));
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
ステップ 2: データを挿入する
タイムゾーンオフセット付きの ISO 8601 文字列を含むエンティティを挿入します。
以下の例では、8,193 行のサンプルデータをコレクションに挿入します。各行には次のものが含まれます。
-
一意の ID
-
タイムゾーンを認識するタイムスタンプ(Shanghai 時間)
-
単純な 4 次元ベクトル
- Python
- Java
- NodeJS
- Go
- cURL
- C++
data_size = 10
# Get the Asia/Shanghai time zone using the pytz library
# You can use any valid IANA time zone identifier such as:
# "Asia/Tokyo", "America/New_York", "Europe/London", "UTC", etc.
# To view all available values:
# import pytz; print(pytz.all_timezones)
# Reference:
# IANA database – https://www.iana.org/time-zones
# Wikipedia – https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
shanghai_tz = pytz.timezone("Asia/Shanghai")
data = [
{
"id": i + 1,
"tsz": shanghai_tz.localize(
datetime.datetime(2025, 1, 1, 0, 0, 0) + datetime.timedelta(days=i)
).isoformat(),
"vec": [float(i) / 10 for i in range(4)],
}
for i in range(data_size)
]
client.insert(collection_name, data)
print("Data inserted successfully.")
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import io.milvus.v2.service.vector.request.InsertReq;
public static List<Float> generateFloatVector(int dimension) {
Random ran = new Random();
List<Float> vector = new ArrayList<>();
for (int i = 0; i < dimension; ++i) {
vector.add(ran.nextFloat());
}
return vector;
}
int rowCount = 10;
ZoneId zone = ZoneId.of("Asia/Shanghai");
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
List<JsonObject> rows = new ArrayList<>();
Gson gson = new Gson();
for (long i = 0L; i < rowCount; ++i) {
JsonObject row = new JsonObject();
row.addProperty("id", i);
row.add("vec", gson.toJsonTree(CommonUtils.generateFloatVector(4)));
LocalDateTime tt = LocalDateTime.of(2025, 1, 1, 0, 0, 0).plusDays(i);
ZonedDateTime zt = tt.atZone(zone);
row.addProperty("tsz", zt.format(formatter));
rows.add(row);
}
client.insert(InsertReq.builder()
.collectionName(collectionName)
.data(rows)
.build());
const dataSize = 10;
const formatDateWithTimezone = (year, month, day, hour, minute, second, timezoneOffset = '+08:00') => {
const monthStr = String(month).padStart(2, '0');
const dayStr = String(day).padStart(2, '0');
const hourStr = String(hour).padStart(2, '0');
const minuteStr = String(minute).padStart(2, '0');
const secondStr = String(second).padStart(2, '0');
return `${year}-${monthStr}-${dayStr}T${hourStr}:${minuteStr}:${secondStr}${timezoneOffset}`;
};
const data = [];
for (let i = 0; i < dataSize; i++) {
const baseDate = new Date(2025, 0, 1 + i, 0, 0, 0);
const year = baseDate.getFullYear();
const month = baseDate.getMonth() + 1;
const day = baseDate.getDate();
const isoString = formatDateWithTimezone(year, month, day, 0, 0, 0, '+08:00');
data.push({
id: i + 1,
tsz: isoString,
vec: Array.from({ length: 4 }, (_, j) => i / 10),
});
}
await client.insert({
collection_name: collectionName,
data: data,
});
// go
curl --request POST \
--url YOUR_CLUSTER_ENDPOINT/v2/vectordb/entities/insert \
--header 'Authorization: Bearer YOUR_CLUSTER_TOKEN' \
--header 'Content-Type: application/json' \
--header "Request-Timeout: 10" \
--data '{ "collectionName": "timestamptz_test123", "data": [ { "id": 1, "tsz": "2026-01-14T19:50:00Z", "vec": [0.1, 0.2, 0.3, 0.4] }, { "id": 2, "tsz": "2026-01-14T12:00:00+08:00", "vec": [0.5, 0.6, 0.7, 0.8] }, { "id": 3, "vec": [0.9, 0.0, 0.1, 0.2] } ] }'
std::string
pad(int num, int width) {
std::ostringstream oss;
oss << std::setw(width) << std::setfill('0') << num;
return oss.str();
}
std::string
formatDateWithTimezone(int year, int month, int day, int hour, int minute, int second,
std::string timezoneOffset = "+08:00") {
std::string ts = std::to_string(year) + "-" + pad(month, 2) + "-" + pad(day, 2) + "T" + pad(hour, 2) + ":" +
pad(minute, 2) + ":" + pad(second, 2) + timezoneOffset;
return ts;
}
milvus::EntityRows rows;
for (auto i = 0; i < 10; i++) {
milvus::EntityRow row;
row["id"] = i;
row["vec"] = std::vector<float>{i/10, (i+1)/10, (i+2)/10, (i+3)/10};
std::string ts = formatDateWithTimezone(2025, 01, i + 1, 0, 0, 0);
row["tsz"] = ts;
rows.emplace_back(std::move(row));
}
auto status = client->Insert(milvus::InsertRequest()
.WithCollectionName(collection_name)
.WithRowsData(std::move(data)).
response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
ステップ 3: フィルタリング操作
TIMESTAMPTZ は、スカラー比較、interval 演算、および時間コンポーネントの抽出をサポートします。
TIMESTAMPTZ フィールドでフィルタリング操作を実行する前に、以下を確認してください。
-
各ベクトルフィールドにインデックスを作成していること。
-
コレクションがメモリにロードされていること。
コード例を表示
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Create index on vector field
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vec",
index_type="AUTOINDEX",
index_name="vec_index",
metric_type="COSINE"
)
client.create_index(collection_name, index_params)
print("Index created successfully.")
# Load the collection
client.load_collection(collection_name)
print(f"Collection '{collection_name}' loaded successfully.")
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.index.request.CreateIndexReq;
List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
.fieldName("vec")
.indexName("vec_index")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.COSINE)
.build());
client.createIndex(CreateIndexReq.builder()
.collectionName(collectionName)
.indexParams(indexes)
.build());
// nodejs
await client.createIndex({
collection_name: collection_name,
field_name: "vec",
index_type: "AUTOINDEX",
index_name: "vec_index",
metric_type: "COSINE"
});
await client.loadCollection({
collection_name: collection_name,
});
// go
curl --request POST \
--url YOUR_CLUSTER_ENDPOINT/v2/vectordb/collections/load \
--header 'Authorization: Bearer YOUR_CLUSTER_TOKEN' \
--header 'Content-Type: application/json' \
--header "Request-Timeout: 10" \
--data '{ "collectionName": "timestamptz_test123" }'
milvus::IndexDesc index_vector("vec", "", milvus::IndexType::AUTOINDEX, milvus::MetricType::COSINE);
auto status = client->CreateIndex(milvus::CreateIndexRequest()
.WithCollectionName(collection_name)
.AddIndex(std::move(index_vector)));
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
status = client->LoadCollection(milvus::LoadCollectionRequest().WithCollectionName(collection_name));
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
タイムスタンプフィルタリングによるクエリ
==、!=、<、>、<=、>= などの算術演算子を使用します。Zilliz Cloud で利用可能な算術演算子の完全な一覧については、Arithmetic Operators を参照してください。
連鎖した範囲式(たとえば lower_bound < tsz < upper_bound)はサポートされていません。
代わりに論理積を使用してください: tsz > lower_bound AND tsz < upper_bound。
以下の例では、タイムスタンプ (tsz) が 2025-01-03T00:00:00+08:00 と等しくないエンティティをフィルタリングします。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Query for entities where tsz is not equal to '2025-01-03T00:00:00+08:00'
expr = "tsz != ISO '2025-01-03T00:00:00+08:00'"
results = client.query(
collection_name=collection_name,
filter=expr,
output_fields=["id", "tsz"],
limit=10
)
print("Query result: ", results)
# Expected output:
# Query result: data: ["{'id': 1, 'tsz': '2024-12-31T16:00:00Z'}", "{'id': 2, 'tsz': '2025-01-01T16:00:00Z'}", "{'id': 4, 'tsz': '2025-01-03T16:00:00Z'}", "{'id': 5, 'tsz': '2025-01-04T16:00:00Z'}", "{'id': 6, 'tsz': '2025-01-05T16:00:00Z'}", "{'id': 7, 'tsz': '2025-01-06T16:00:00Z'}", "{'id': 8, 'tsz': '2025-01-07T16:00:00Z'}", "{'id': 9, 'tsz': '2025-01-08T16:00:00Z'}", "{'id': 10, 'tsz': '2025-01-09T16:00:00Z'}", "{'id': 11, 'tsz': '2025-01-10T16:00:00Z'}"]
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
String filter = "tsz != ISO '2025-01-03T00:00:00+08:00'";
QueryResp queryRet = client.query(QueryReq.builder()
.collectionName(collectionName)
.filter(filter)
.outputFields(Arrays.asList("id", "tsz"))
.limit(10)
.build());
List<QueryResp.QueryResult> records = queryRet.getQueryResults();
for (QueryResp.QueryResult record : records) {
System.out.println(record.getEntity());
}
const expr = "tsz != ISO '2025-01-03T00:00:00+08:00'"
const results = await client.query({
collection_name,
filter: expr,
output_fields: ["id", "tsz"],
limit: 10
});
console.log(results);
// go
curl --request POST \
--url YOUR_CLUSTER_ENDPOINT/v2/vectordb/entities/query \
--header 'Authorization: Bearer YOUR_CLUSTER_TOKEN' \
--header 'Content-Type: application/json' \
--header "Request-Timeout: 10" \
--data '{
"collectionName": "timestamptz_test123",
"filter": "tsz != ISO '\''2025-01-03T00:00:00+08:00'\''",
"outputFields": ["id", "tsz"],
"limit": 10
}'
std::string filter = "tsz != ISO '2025-01-03T00:00:00+08:00'";
auto request = milvus::QueryRequest()
.WithCollectionName(collection_name)
.WithFilter(filter)
.AddOutputField("id")
.AddOutputField("tsz")
.WithLimit(10);
milvus::QueryResponse response;
auto status = client->Query(request, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
milvus::EntityRows output_rows;
status = query_results.OutputRows(output_rows);
for (const auto& row : output_rows) {
std::cout << "\t" << row << std::endl;
}
上記の例では、
-
tszはスキーマで定義されたTIMESTAMPTZフィールド名です。 -
ISO '2025-01-03T00:00:00+08:00'は、タイムゾーンオフセットを含む ISO 8601 形式のタイムスタンプリテラルです。 -
!=はフィールド値をそのリテラルと比較します。その他にサポートされている演算子には、==、<、<=、>、>=があります。
INTERVAL 演算
ISO 8601 duration format の INTERVAL 値を使用して、TIMESTAMPTZ フィールドに対して算術演算を実行できます。これにより、データをフィルタリングする際に、タイムスタンプへ日、時間、分などの期間を加算または減算できます。
たとえば、次のクエリでは、タイムスタンプ (tsz) に 0 日を加算した結果が 2025-01-03T00:00:00+08:00 と 等しくない エンティティをフィルタリングします。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
expr = "tsz + INTERVAL 'P0D' != ISO '2025-01-03T00:00:00+08:00'"
results = client.query(
collection_name,
filter=expr,
output_fields=["id", "tsz"],
limit=10
)
print("Query result: ", results)
# Expected output:
# Query result: data: ["{'id': 1, 'tsz': '2024-12-31T16:00:00Z'}", "{'id': 2, 'tsz': '2025-01-01T16:00:00Z'}", "{'id': 4, 'tsz': '2025-01-03T16:00:00Z'}", "{'id': 5, 'tsz': '2025-01-04T16:00:00Z'}", "{'id': 6, 'tsz': '2025-01-05T16:00:00Z'}", "{'id': 7, 'tsz': '2025-01-06T16:00:00Z'}", "{'id': 8, 'tsz': '2025-01-07T16:00:00Z'}", "{'id': 9, 'tsz': '2025-01-08T16:00:00Z'}", "{'id': 10, 'tsz': '2025-01-09T16:00:00Z'}", "{'id': 11, 'tsz': '2025-01-10T16:00:00Z'}"]
String filter = "tsz + INTERVAL 'P0D' != ISO '2025-01-03T00:00:00+08:00'";
QueryResp queryRet = client.query(QueryReq.builder()
.collectionName(collectionName)
.filter(filter)
.outputFields(Arrays.asList("id", "tsz"))
.limit(10)
.build());
List<QueryResp.QueryResult> records = queryRet.getQueryResults();
for (QueryResp.QueryResult record : records) {
System.out.println(record.getEntity());
}
const expr = "tsz + INTERVAL 'P0D' != ISO '2025-01-03T00:00:00+08:00'";
const results = await client.query({
collection_name,
filter: expr,
output_fields: ["id", "tsz"],
limit: 10
});
console.log(results);
// go
curl --request POST \
--url YOUR_CLUSTER_ENDPOINT/v2/vectordb/entities/query \
--header 'Authorization: Bearer YOUR_CLUSTER_TOKEN' \
--header 'Content-Type: application/json' \
--header "Request-Timeout: 10" \
--data '{ "collectionName": "timestamptz_test123", "filter": "tsz + INTERVAL '\''P0D'\'' != ISO '\''2025-01-03T00:00:00+08:00'\''", "outputFields": ["id", "tsz"], "limit": 10 }'
std::string filter = "tsz + INTERVAL 'P0D' != ISO '2025-01-03T00:00:00+08:00'";
auto request = milvus::QueryRequest()
.WithCollectionName(collection_name)
.WithFilter(filter)
.AddOutputField("id")
.AddOutputField("tsz")
.WithLimit(10);
milvus::QueryResponse response;
auto status = client->Query(request, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
milvus::EntityRows output_rows;
status = query_results.OutputRows(output_rows);
for (const auto& row : output_rows) {
std::cout << "\t" << row << std::endl;
}
INTERVAL 値は ISO 8601 duration syntax に従います。例:
-
P1D→ 1 日 -
PT3H→ 3 時間 -
P2DT6H→ 2 日と 6 時間
次のように、フィルタ式の中で INTERVAL の算術演算を直接使用できます。
-
tsz + INTERVAL 'P3D'→ 3 日を加算 -
tsz - INTERVAL 'PT2H'→ 2 時間を減算
タイムスタンプフィルタリングによる検索
TIMESTAMPTZ フィルタリングをベクトル類似度検索と組み合わせることで、時間と類似度の両方で結果を絞り込めます。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Define a time-based filter expression
filter = "tsz > ISO '2025-01-05T00:00:00+08:00'"
res = client.search(
collection_name=collection_name, # Collection name
data=[[0.1, 0.2, 0.3, 0.4]], # Query vector (must match collection's vector dim)
limit=5, # Max. number of results to return
filter=filter, # Filter expression using TIMESTAMPTZ
output_fields=["id", "tsz"], # Fields to include in the search results
)
print("Search result: ", res)
# Expected output:
# Search result: data: [[{'id': 10, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-09T16:00:00Z', 'id': 10}}, {'id': 9, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-08T16:00:00Z', 'id': 9}}, {'id': 8, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-07T16:00:00Z', 'id': 8}}, {'id': 7, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-06T16:00:00Z', 'id': 7}}, {'id': 6, 'distance': 0.9759000539779663, 'entity': {'tsz': '2025-01-05T16:00:00Z', 'id': 6}}]]
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
String filter = "tsz > ISO '2025-01-05T00:00:00+08:00'";
SearchResp searchR = client.search(SearchReq.builder()
.collectionName(collectionName)
.data(Collections.singletonList(new FloatVec(new float[]{0.1f, 0.2f, 0.3f, 0.4f})))
.limit(5)
.filter(filter)
.outputFields(Arrays.asList("id", "tsz"))
.build());
List<List<SearchResp.SearchResult>> searchResults = searchR.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
for (SearchResp.SearchResult result : results) {
System.out.printf("ID: %d, Score: %f, %s\n", (long) result.getId(), result.getScore(), result.getEntity().toString());
}
}
const expr = "tsz > ISO '2025-01-05T00:00:00+08:00'";
const results = await client.search({
collection_name,
data=[[0.1, 0.2, 0.3, 0.4]], // Query vector (must match collection's vector dim)
filter: expr,
output_fields: ["id", "tsz"],
limit: 5
});
console.log(results);
// go
curl --request POST \
--url YOUR_CLUSTER_ENDPOINT/v2/vectordb/entities/search \
--header 'Authorization: Bearer YOUR_CLUSTER_TOKEN' \
--header 'Content-Type: application/json' \
--header "Request-Timeout: 10" \
--data '{ "collectionName": "timestamptz_test123", "data": [[0.1, 0.2, 0.3, 0.4]], "limit": 5, "filter": "tsz > ISO '\''2025-01-05T00:00:00+08:00'\''", "outputFields": ["id", "tsz"] }'
std::string filter = "tsz > ISO '2025-01-05T00:00:00+08:00'";
std::vector<float> query_vector = {0.1, 0.2, 0.3, 0.4};
auto request = milvus::SearchRequest()
.WithCollectionName(collection_name)
.WithFilter(filter)
.WithLimit(5)
.AddOutputField("id")
.AddOutputField("tsz")
.AddFloatVector(query_vector);
milvus::SearchResponse response;
auto status = client->Search(request, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
auto search_results = response.Results();
for (auto& result : search_results.Results()) {
milvus::EntityRows output_rows;
status = result.OutputRows(output_rows);
for (const auto& row : output_rows) {
std::cout << "\t" << row << std::endl;
}
}
コレクションに 2 つ以上のベクトルフィールドがある場合、タイムスタンプフィルタリングを使ったハイブリッド検索を実行できます。詳細は Multi-Vector Hybrid Search を参照してください。
高度な使用法
高度な使用法として、異なるレベル(たとえばデータベース、コレクション、クエリ)でタイムゾーンを管理したり、インデックスを使用して TIMESTAMPTZ フィールドへのクエリを高速化したりできます。
異なるレベルでタイムゾーンを管理する
TIMESTAMPTZ フィールドのタイムゾーンは、コレクション レベルまたは クエリ/検索 レベルで制御できます。
| Level | Parameter | Scope | Priority |
|---|---|---|---|
| Collection | timezone | そのコレクションに対してデータベースのデフォルトタイムゾーン設定を上書き | Medium |
| Query/search/hybrid search | timezone | 特定の 1 回の操作に対する一時的な上書き | Highest |
手順ごとの説明とコードサンプルについては、以下の専用ページを参照してください。
クエリを高速化する
デフォルトでは、インデックスのない TIMESTAMPTZ フィールドへのクエリはすべての行に対してフルスキャンを実行するため、大規模なデータセットでは低速になる可能性があります。タイムスタンプクエリを高速化するには、TIMESTAMPTZ フィールドに AUTOINDEX インデックスを作成してください。
詳細は STL_SORT を参照してください。