Campo TIMESTAMPTZCompatible with Milvus 2.6.6+
Le applicazioni che tengono traccia dell'ora da una regione all'altra, come i sistemi di e-commerce, gli strumenti di collaborazione o la registrazione distribuita, hanno bisogno di una gestione precisa dei timestamp con i fusi orari. Il tipo di dati TIMESTAMPTZ di Milvus offre questa possibilità , 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) di Milvus che elabora l'input consapevole del 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)).Memorizzazione interna: Tutti i valori di
TIMESTAMPTZsono normalizzati e memorizzati in tempo universale coordinato (UTC).Confronto e filtraggio: Tutte le operazioni di filtraggio e ordinamento vengono eseguite in UTC, garantendo risultati coerenti e prevedibili in diversi fusi orari.
È possibile impostare
nullable=Trueper i campiTIMESTAMPTZin modo da consentire valori mancanti.È possibile specificare un valore di timestamp predefinito utilizzando l'attributo
default_valuenel formato ISO 8601.
Per maggiori dettagli, vedere Nullable e Default.
Operazioni di base
Il flusso di lavoro di base per l'utilizzo di un campo TIMESTAMPTZ rispecchia gli altri campi scalari di Milvus: definire il campo → inserire i dati → interrogare/filtrare.
Passo 1: Definire un campo TIMESTAMPTZ
Per utilizzare un campo TIMESTAMPTZ, è necessario definirlo esplicitamente nello schema della raccolta durante la creazione della stessa. L'esempio seguente mostra 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
Passo 2: Inserire i dati
Inserire entità contenenti stringhe ISO 8601 con offset di fuso orario.
L'esempio seguente inserisce 8.193 righe di dati di esempio nella raccolta. 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
Passo 3: operazioni di filtraggio
TIMESTAMPTZ supporta i confronti scalari, l'aritmetica degli intervalli e l'estrazione delle componenti temporali.
Prima di poter eseguire operazioni di filtraggio sui campi di TIMESTAMPTZ, accertarsi che:
Sia stato creato un indice su ciascun campo vettoriale.
L'insieme sia stato caricato 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 filtraggio del timestamp
Utilizzare operatori aritmetici come ==, !=, <, >, <=, >=. Per un elenco completo degli operatori aritmetici disponibili in Milvus, consultare Operatori aritmetici.
L'esempio seguente filtra le entità con timestamp (tsz) che non sono uguali a 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 precedente,
tszè il nome del campoTIMESTAMPTZdefinito nello schema.ISO '2025-01-03T00:00:00+08:00'è un letterale di timestamp nel formato ISO 8601, compreso l'offset del fuso orario.!=confronta il valore del campo con tale letterale. Altri operatori supportati sono==,<,<=,>e>=.
Operazioni sugli intervalli
È possibile eseguire operazioni aritmetiche sui campi di TIMESTAMPTZ utilizzando i valori INTERVALLO nel formato di durata ISO 8601. Ciò consente di aggiungere o sottrarre durate, come giorni, ore o minuti, da un timestamp quando si filtrano i dati.
Ad esempio, la query seguente 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 di durata ISO 8601. Ad esempio:
P1D→ 1 giornoPT3H→ 3 oreP2DT6H→ 2 giorni e 6 ore
È possibile utilizzare l'aritmetica di INTERVAL direttamente nelle espressioni di filtro, come ad esempio:
tsz + INTERVAL 'P3D'→ Aggiunge 3 giornitsz - INTERVAL 'PT2H'→ Sottrae 2 ore
Ricerca con filtro temporale
È possibile combinare il filtro 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 raccolta ha due o più campi vettoriali, è possibile eseguire operazioni di ricerca ibride con il filtraggio del timestamp. Per maggiori dettagli, consultare la sezione Ricerca ibrida multivettoriale.
Uso avanzato
Per un uso avanzato, è possibile gestire i fusi orari a diversi livelli (ad esempio, database, collezione o query) o accelerare le query sui campi TIMESTAMPTZ usando gli indici.
Gestione dei fusi orari a diversi livelli
È possibile controllare il fuso orario per i campi di TIMESTAMPTZ a livello di database, raccolta o query/ricerca.
Livello |
Parametro |
Ambito |
Priorità |
|---|---|---|---|
Database |
|
Predefinito per tutte le raccolte del database |
Più basso |
Collezione |
|
Sovrascrive l'impostazione predefinita del fuso orario del database per quella raccolta |
Media |
Query/ricerca/ricerca ibrida |
|
Sovrascrittura temporanea per un'operazione specifica |
Massima |
Per istruzioni passo-passo ed esempi di codice, consultare le pagine dedicate:
Accelerare le query
Per impostazione predefinita, le query sui campi TIMESTAMPTZ senza indice eseguono una scansione completa di tutte le righe, che può essere lenta su grandi insiemi di dati. Per accelerare le query sui timestamp, creare un indice STL_SORT sul campo TIMESTAMPTZ.
Per i dettagli, consultare STL_SORT.