Campo TIMESTAMPTZCompatible with Milvus 2.6.6+
Le applicazioni che gestiscono il tempo su più regioni, come i sistemi di e-commerce, gli strumenti di collaborazione o la registrazione distribuita, richiedono una gestione precisa dei timestamp con i fusi orari. Il tipo di dati TIMESTAMPTZ in Milvus offre questa funzionalità memorizzando i timestamp con il fuso orario associato.
Che cos’è un campo TIMESTAMPTZ?
Un campo TIMESTAMPTZ è un tipo di dati definito dallo schema (DataType.TIMESTAMPTZ) in Milvus che elabora input sensibili al fuso orario e memorizza internamente tutti i punti temporali come ora assoluta UTC:
Formato di input accettato: stringhe ISO 8601 con un offset di fuso orario (ad esempio,
"2025-05-01T23:59:59+08:00"indica le 23:59:59 del 1° maggio 2025 (UTC+08:00)).Archiviazione interna: tutti i valori
TIMESTAMPTZvengono normalizzati e memorizzati nel Tempo Universale Coordinato (UTC).Confronto e filtraggio: tutte le operazioni di filtraggio e ordinamento vengono eseguite in UTC, garantendo risultati coerenti e prevedibili nei diversi fusi orari.
È possibile impostare l’attributo "
nullable=True" per i campi "TIMESTAMPTZ" in modo da consentire la presenza di valori mancanti.È possibile specificare un valore di timestamp predefinito utilizzando l'attributo "
default_value" nel formato ISO 8601.
Per ulteriori dettagli, consultare la sezione " Nullable & Default ".
Operazioni di base
Il flusso di lavoro di base per l’utilizzo di un campo TIMESTAMPTZ rispecchia quello degli altri campi scalari in Milvus: definire il campo → inserire i dati → eseguire query/filtrare.
Passo 1: Definire un campo TIMESTAMPTZ
Per utilizzare un campo ` TIMESTAMPTZ `, definirlo esplicitamente nello schema della collezione al momento della creazione della stessa. L’esempio seguente illustra come creare una collezione con un campo ` tsz ` di tipo ` DataType.TIMESTAMPTZ`.
import time
from pymilvus import MilvusClient, DataType
import datetime
import pytz
server_address = "http://localhost:19530"
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.")
// java
// nodejs
// go
# restful
Passaggio 2: Inserimento dei dati
Inserire entità contenenti stringhe ISO 8601 con offset di fuso orario.
L'esempio riportato di seguito inserisce 8.193 righe di dati di esempio nella collezione. Ogni riga include:
un ID univoco
un timestamp che tiene conto del fuso orario (ora di Shanghai)
un semplice vettore a 4 dimensioni
data_size = 8193
# 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.")
// java
// nodejs
// go
# restful
Passaggio 3: Operazioni di filtraggio
TIMESTAMPTZ supporta confronti scalari, aritmetica degli intervalli ed estrazione delle componenti temporali.
Prima di poter eseguire operazioni di filtraggio sui campi di un TIMESTAMPTZ, assicurati che:
Di aver creato un indice su ciascun campo vettoriale.
La collezione sia caricata in memoria.
# 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.")
// java
// nodejs
// go
# restful
Query con filtro per timestamp
Utilizza operatori aritmetici come ==, !=, <, >, <=, >=. Per un elenco completo degli operatori aritmetici disponibili in Milvus, consulta Operatori aritmetici.
L'esempio riportato di seguito filtra le entità con timestamp (tsz) diversi da 2025-01-03T00:00:00+08:00:
# 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'}"]
// java
// nodejs
// go
# restful
Nell’esempio sopra riportato,
tszè il nome del campoTIMESTAMPTZdefinito nello schema.ISO '2025-01-03T00:00:00+08:00'è un letterale di timestamp in formato ISO 8601, comprensivo dell’offset del fuso orario.!=confronta il valore del campo con quel valore letterale. Altri operatori supportati includono==,<,<=,>e>=.
Operazioni sugli intervalli
È possibile eseguire operazioni aritmetiche sui campi TIMESTAMPTZ utilizzando valori INTERVAL nel formato di durata ISO 8601. Ciò consente di aggiungere o sottrarre durate, quali giorni, ore o minuti, da un timestamp durante il filtraggio dei dati.
Ad esempio, la seguente query filtra le entità in cui il timestamp (tsz) più zero giorni non è uguale a 2025-01-03T00:00:00+08:00:
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'}"]
// java
// nodejs
// go
# restful
INTERVAL I valori seguono la sintassi della durata ISO 8601. Ad esempio:
P1D→ 1 giornoPT3H→ 3 oreP2DT6H→ 2 giorni e 6 ore
È possibile utilizzare direttamente l'aritmetik INTERVAL a nelle espressioni di filtro, ad esempio:
tsz + INTERVAL 'P3D'→ Aggiunge 3 giornitsz - INTERVAL 'PT2H'→ Sottrae 2 ore
Ricerca con filtro basato sul timestamp
È possibile combinare il filtraggio " TIMESTAMPTZ " con la ricerca per similarità vettoriale per restringere i risultati sia in base al tempo che alla similarità.
# 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}}]]
// java
// nodejs
// go
# restful
Se la propria raccolta dispone di due o più campi vettoriali, è possibile eseguire operazioni di ricerca ibrida con il filtro per timestamp. Per ulteriori dettagli, consultare Ricerca ibrida multivettoriale.
Utilizzo avanzato
Per un utilizzo avanzato, è possibile gestire i fusi orari a diversi livelli (ad esempio, database, raccolta o query) oppure accelerare le query sui campi " TIMESTAMPTZ " utilizzando gli indici.
Gestire i fusi orari a diversi livelli
È possibile controllare il fuso orario per i campi " TIMESTAMPTZ " a livello di database, raccolta o query/ricerca.
Livello |
Parametro |
Ambito |
Priorità |
|---|---|---|---|
Database |
|
Impostazione predefinita per tutte le raccolte nel database |
Minima |
Raccolta |
|
Sovrascrive l'impostazione predefinita del fuso orario del database per quella raccolta |
Medio |
Query/ricerca/ricerca ibrida |
|
Sostituzioni temporanee per una specifica operazione |
Massimo |
Per istruzioni dettagliate ed esempi di codice, consultare le pagine dedicate:
Accelerare le query
Per impostazione predefinita, le query sui campi TIMESTAMPTZ privi di indice eseguono una scansione completa di tutte le righe, operazione che può risultare lenta su set di dati di grandi dimensioni. Per accelerare le query basate su timestamp, creare un indice STL_SORT sul campo TIMESTAMPTZ.
Per ulteriori dettagli, consultare STL_SORT.