Поле TIMESTAMPTZCompatible with Milvus 2.6.6+
Приложениям, которые отслеживают время в разных регионах, например, системам электронной коммерции, инструментам совместной работы или распределенному протоколированию, необходима точная обработка временных меток с учетом часовых поясов. Тип данных TIMESTAMPTZ в Milvus предоставляет такую возможность, сохраняя временные метки с привязкой к часовому поясу.
Что такое поле TIMESTAMPTZ?
Поле TIMESTAMPTZ - это определяемый схемой тип данных (DataType.TIMESTAMPTZ) в Milvus, который обрабатывает входные данные с учетом часовых поясов и хранит все временные точки в виде абсолютного времени UTC:
Принимаемый формат ввода: Строки ISO 8601 со смещением часового пояса (например,
"2025-05-01T23:59:59+08:00"обозначает 11:59:59 PM 1 мая 2025 года (UTC+08:00)).Внутреннее хранение: Все значения
TIMESTAMPTZнормализуются и хранятся в универсальном координированном времени (UTC).Сравнение и фильтрация: Все операции фильтрации и упорядочивания выполняются в UTC, что обеспечивает последовательные и предсказуемые результаты в разных часовых поясах.
Для полей
TIMESTAMPTZможно установить значениеnullable=True, допускающее пропущенные значения.Вы можете указать значение временной метки по умолчанию с помощью атрибута
default_valueв формате ISO 8601.
Подробности см. в разделе Нулевые и по умолчанию.
Основные операции
Основной рабочий процесс использования поля TIMESTAMPTZ повторяет другие скалярные поля в Milvus: определение поля → вставка данных → запрос/фильтр.
Шаг 1: Определение поля TIMESTAMPTZ
Чтобы использовать поле TIMESTAMPTZ, явно определите его в схеме коллекции при создании коллекции. В следующем примере показано, как создать коллекцию с полем tsz типа 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
Шаг 2: Вставка данных
Вставьте сущности, содержащие строки ISO 8601 со смещениями часовых поясов.
В приведенном ниже примере в коллекцию вставляется 8 193 строки данных образца. Каждая строка включает:
уникальный идентификатор
временную метку с учетом часового пояса (шанхайское время)
простой 4-мерный вектор
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
Шаг 3: Операции фильтрации
TIMESTAMPTZ поддерживает скалярные сравнения, интервальную арифметику и извлечение компонентов времени.
Прежде чем выполнять операции фильтрации полей TIMESTAMPTZ, убедитесь, что:
Вы создали индекс для каждого векторного поля.
Коллекция загружена в память.
# 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
Запрос с фильтрацией по меткам времени
Используйте арифметические операторы, такие как ==, !=, <, >, <=, >=. Полный список арифметических операторов, доступных в Milvus, приведен в разделе Арифметические операторы.
В примере ниже фильтруются сущности с временными метками (tsz), которые не равны 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
В примере выше,
tszэто имя поляTIMESTAMPTZ, определенное в схеме.ISO '2025-01-03T00:00:00+08:00'литерал временной метки в формате ISO 8601, включая смещение часового пояса.!=сравнивает значение поля с этим литералом. Другие поддерживаемые операторы:==,<,<=,>и>=.
Интервальные операции
Вы можете выполнять арифметические операции над полями TIMESTAMPTZ, используя значения INTERVAL в формате длительности ISO 8601. Это позволяет добавлять или вычитать длительности, такие как дни, часы или минуты, из временной метки при фильтрации данных.
Например, следующий запрос фильтрует сущности, в которых временная метка (tsz) плюс ноль дней не равна 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 Значения соответствуют синтаксису длительности ISO 8601. Например:
P1D→ 1 деньPT3H→ 3 часаP2DT6H→ 2 дня и 6 часов
Вы можете использовать арифметику INTERVAL непосредственно в выражениях фильтра, например:
tsz + INTERVAL 'P3D'→ Добавляет 3 дняtsz - INTERVAL 'PT2H'→ Вычитает 2 часа
Поиск с фильтрацией по меткам времени
Вы можете комбинировать фильтрацию TIMESTAMPTZ с поиском по векторному сходству, чтобы сузить результаты как по времени, так и по сходству.
# 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
Если коллекция содержит два или более векторных полей, вы можете выполнять гибридные операции поиска с фильтрацией по меткам времени. Подробнее см. в разделе Многовекторный гибридный поиск.
Расширенное использование
Для расширенного использования можно управлять временными зонами на разных уровнях (например, в базе данных, коллекции или запросе) или ускорять запросы к полям TIMESTAMPTZ с помощью индексов.
Управление часовыми поясами на разных уровнях
Вы можете управлять часовым поясом для полей TIMESTAMPTZ на уровне базы данных, коллекции или запроса/поиска.
Уровень |
Параметр |
Область применения |
Приоритет |
|---|---|---|---|
База данных |
|
По умолчанию для всех коллекций в базе данных |
Самый низкий |
Коллекция |
|
Отменяет настройку часового пояса по умолчанию базы данных для данной коллекции |
Средняя |
Запрос/поиск/гибридный поиск |
|
Временные переопределения для одной конкретной операции |
Самый высокий |
Пошаговые инструкции и примеры кода см. на соответствующих страницах:
Ускорение запросов
По умолчанию запросы к полям TIMESTAMPTZ без индекса выполняют полное сканирование всех строк, что может быть медленным при работе с большими массивами данных. Чтобы ускорить запросы к временным меткам, создайте индекс STL_SORT для поля TIMESTAMPTZ.
Подробности см. в разделе STL_SORT.