Champ TIMESTAMPTZCompatible with Milvus 2.6.6+
Les applications qui suivent le temps à travers les régions, telles que les systèmes de commerce électronique, les outils de collaboration ou la journalisation distribuée, ont besoin d'un traitement précis des horodatages avec les fuseaux horaires. Le type de données TIMESTAMPTZ dans Milvus offre cette possibilité en stockant les horodatages avec leur fuseau horaire associé.
Qu'est-ce qu'un champ TIMESTAMPTZ ?
Un champ TIMESTAMPTZ est un type de données défini par le schéma (DataType.TIMESTAMPTZ) dans Milvus qui traite les entrées tenant compte des fuseaux horaires et stocke tous les points temporels en interne en tant qu'heure absolue UTC :
Format d'entrée accepté: Format d'entrée accepté : chaînes ISO 8601 avec un décalage de fuseau horaire (par exemple,
"2025-05-01T23:59:59+08:00"indique 11:59:59 PM le 1er mai 2025 (UTC+08:00)).Stockage interne: Toutes les valeurs de
TIMESTAMPTZsont normalisées et stockées en temps universel coordonné (UTC).Comparaison et filtrage: Toutes les opérations de filtrage et de classement sont effectuées en UTC, ce qui garantit des résultats cohérents et prévisibles dans différents fuseaux horaires.
Vous pouvez définir
nullable=Truepour les champsTIMESTAMPTZafin d'autoriser les valeurs manquantes.Vous pouvez spécifier une valeur d'horodatage par défaut à l'aide de l'attribut
default_valueau format ISO 8601.
Voir Nullable & Default pour plus de détails.
Opérations de base
Le flux de travail de base de l'utilisation d'un champ TIMESTAMPTZ reflète les autres champs scalaires de Milvus : définir le champ → insérer des données → interroger/filtrer.
Étape 1 : Définition d'un champ TIMESTAMPTZ
Pour utiliser un champ TIMESTAMPTZ, définissez-le explicitement dans votre schéma de collection lors de la création de la collection. L'exemple suivant montre comment créer une collection avec un champ tsz de type 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
Étape 2 : Insérer des données
Insérez des entités contenant des chaînes ISO 8601 avec des décalages de fuseaux horaires.
L'exemple ci-dessous insère 8 193 lignes de données d'échantillonnage dans la collection. Chaque ligne comprend
un identifiant unique
un horodatage tenant compte du fuseau horaire (heure de Shanghai)
un simple vecteur à 4 dimensions
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
Étape 3 : Opérations de filtrage
TIMESTAMPTZ supporte les comparaisons scalaires, l'arithmétique d'intervalle et l'extraction de composantes temporelles.
Avant de pouvoir effectuer des opérations de filtrage sur les champs TIMESTAMPTZ, vous devez vous assurer que
Vous avez créé un index sur chaque champ vectoriel.
La collection est chargée en mémoire.
# 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
Requête avec filtrage de l'horodatage
Utilisez les opérateurs arithmétiques comme ==, !=, <, >, <=, >=. Pour une liste complète des opérateurs arithmétiques disponibles dans Milvus, voir Opérateurs arithmétiques.
L'exemple ci-dessous filtre les entités dont l'horodatage (tsz) n'est pas égal à 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
Dans l'exemple ci-dessus,
tszest le nom du champTIMESTAMPTZdéfini dans le schéma.ISO '2025-01-03T00:00:00+08:00'est un littéral d'horodatage au format ISO 8601, y compris son décalage de fuseau horaire.!=compare la valeur du champ à ce littéral. Les autres opérateurs pris en charge sont==,<,<=,>et>=.
Opérations sur les intervalles
Vous pouvez effectuer des opérations arithmétiques sur les champs TIMESTAMPTZ en utilisant les valeurs INTERVAL dans le format de durée ISO 8601. Cela vous permet d'ajouter ou de soustraire des durées, telles que des jours, des heures ou des minutes, à un horodatage lors du filtrage des données.
Par exemple, la requête suivante filtre les entités dont l'horodatage (tsz) plus zéro jour n'est pas égal à 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 suivent la syntaxe de durée ISO 8601. Par exemple, les valeurs cURL suivent la syntaxe de durée ISO 8601 :
P1D→ 1 jourPT3H→ 3 heuresP2DT6H→ 2 jours et 6 heures
Vous pouvez utiliser l'arithmétique INTERVAL directement dans les expressions de filtre, comme par exemple :
tsz + INTERVAL 'P3D'→ Ajoute 3 jourstsz - INTERVAL 'PT2H'→ Soustrait 2 heures
Recherche avec filtrage par horodatage
Vous pouvez combiner le filtrage TIMESTAMPTZ avec la recherche de similarité vectorielle pour limiter les résultats en fonction du temps et de la 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
Si votre collection comporte deux champs vectoriels ou plus, vous pouvez effectuer des opérations de recherche hybrides avec le filtrage par horodatage. Pour plus d'informations, reportez-vous à la section Recherche hybride multi-vecteurs.
Utilisation avancée
Pour une utilisation avancée, vous pouvez gérer les fuseaux horaires à différents niveaux (base de données, collection ou requête) ou accélérer les requêtes sur les champs TIMESTAMPTZ à l'aide d'index.
Gestion des fuseaux horaires à différents niveaux
Vous pouvez contrôler le fuseau horaire des champs TIMESTAMPTZ au niveau de la base de données, de la collection ou de la requête/recherche.
Niveau |
Paramètre |
Champ d'application |
Priorité |
|---|---|---|---|
Base de données |
|
Valeur par défaut pour toutes les collections de la base de données |
La plus basse |
Collection |
|
Remplace le fuseau horaire par défaut de la base de données pour cette collection |
Moyen |
Requête/recherche/recherche hybride |
|
Modifications temporaires pour une opération spécifique |
Plus élevé |
Pour obtenir des instructions étape par étape et des exemples de code, consultez les pages dédiées :
Accélérer les requêtes
Par défaut, les requêtes sur les champs TIMESTAMPTZ sans index effectuent un balayage complet de toutes les lignes, ce qui peut être lent sur les grands ensembles de données. Pour accélérer les requêtes d'horodatage, créez un index STL_SORT sur votre champ TIMESTAMPTZ.
Pour plus d'informations, reportez-vous à STL_SORT.