Допустим, у вашего товара в основной базе уже есть ID 550e8400-e29b-41d4-a716-446655440000. Он попадает в события, логи и ответы API. Но при загрузке того же товара в Manticore приложению приходится выдавать ему ещё один, числовой ID.
До Manticore Search 28.5.0 ID документа был беззнаковым 64-битным числом. UUID можно было сохранить в отдельном строковом атрибуте, однако идентификатором документа он от этого не становился. Для UPDATE, REPLACE и DELETE всё равно требовался числовой id.
В результате приходилось хранить соответствие между UUID из основной БД и числовым ID в таблице Manticore. Теперь без него можно обойтись: RT-таблица Manticore умеет использовать UUID как ID документа.
Почему второй ID мешает
Таблица соответствий между айдишниками - это конечно не то чтоб сильно сложно, но только пока приложение загружает данные и выполняет поиск. Сложности начинаются при изменении документов.
Воркер получает событие с UUID, находит соответствующий числовой ID и только после этого отправляет обновление в Manticore. Удаление проходит по той же схеме. Если запись о соответствии пропала или устарела, может обновиться не тот документ либо изменения вообще не попадут в Manticore.
Другой сценарий — превратить UUID в 64-битный хеш. Тогда приложение должно само учитывать возможность коллизии. Можно также завести отдельный последовательный счётчик, но его придётся согласовывать между всеми процессами, которые создают документы.
С числовым ID связана ещё одна тонкость — уже на уровне API. Внутри Manticore это uint64, а SQL показывает его как знаковый BIGINT. Поэтому SQL может вернуть значения больше 2^63-1 в виде отрицательных чисел, и клиенту приходится аккуратно их преобразовывать. UUID передаётся и возвращается строкой, поэтому о знаковом диапазоне и переполнении можно не беспокоиться.
id uuid решает проблему на корню: идентификатор объекта больше не нужно преобразовывать. Один и тот же UUID используется в основной БД, очереди, Manticore, логах и внешнем API.
Что такое UUID
UUID по сути своей - это 128-битный идентификатор, для создания которого не нужен центральный реестр. В текстовом виде он обычно состоит из 36 символов: 32 шестнадцатеричных цифр и четырёх дефисов.
550e8400-e29b-41d4-a716-446655440000
В UUID заложены версия и variant. Версия определяет способ формирования остальных битов. UUIDv4 строится на случайных или псевдослучайных данных. UUIDv7 включает временную составляющую и сохраняет хронологический порядок идентификаторов. В UUIDv8 расположение остальных битов определяет конкретная реализация.
Отсутствие центральной регистрации позволяет назначить ID ещё до записи в общую базу. Например, два независимых сервиса могут создавать объекты параллельно, а какой-нибудь мобильный клиент, который не ловит LTE — подготовить данные без подключения к серверу. После синхронизации объект сохранит тот же идентификатор.
Однако, UUID не стоит считать абсолютной гарантией уникальности. На практике она зависит от корректности выбранного генератора. Также имейте в виду, что UUID не является секретом и не заменяет пароль, токен или проверку прав.
Что появилось в Manticore 28.5.0
Для RT-таблицы теперь можно явно задать тип ID документа:
CREATE TABLE products_uuid (
id uuid,
title text,
sku string,
price int
);
INSERT INTO products_uuid (id, title, sku, price)
VALUES (
'550e8400-e29b-41d4-a716-446655440000',
'Mechanical keyboard',
'KB-001',
149
);
После вставки этот же UUID может использоваться в фильтрах по равенству и IN, а также в UPDATE, REPLACE и DELETE. SQL возвращает ID как строку. Передать явный UUID или попросить Manticore создать ID можно и через JSON API; подробные запросы и ответы разберём в следующей статье.
В случае повторного INSERT с уже существующим UUID, Manticore отклонит его, как и раньше с числовым id. Для перезаписи документа по ID используется REPLACE.
Стоит заметить, что тип uuid относится только к ID документа. Объявить обычный пользовательский атрибут с типом uuid нельзя.
Кто создаёт UUID
Есть два варианта:
| Как записан документ | Кто создаёт ID | Что делает Manticore |
|---|---|---|
Поле id передано | Основная БД, клиентская библиотека или другой компонент системы | Проверяет формат, версию и variant, затем сохраняет UUID в нижнем регистре |
Поле id отсутствует | Manticore | Создаёт UUIDv8 и кодирует в нём внутренний числовой auto-ID |
Если UUID уже создаёт приложение, подстраивать его под Manticore не нужно. Формат обычный: пять групп 8-4-4-4-12. Версия может быть любой от v1 до v8, а в позиции variant должна стоять 8, 9, a или b. Регистр не важен: UUID можно прислать заглавными буквами, но Manticore сохранит его строчными.
На этом проверка заканчивается: Manticore проверяет формат UUID, но не качество генерации. За случайность UUIDv4 и корректную временную часть UUIDv7 отвечает клиентская библиотека.
Генерация на стороне сервера устроена иначе. Если поле id не передано, Manticore создаёт UUIDv8 собственной структуры и кодирует в нём штатный числовой auto-ID. Это не случайный UUIDv4 и не секретное значение.
UUIDv8, созданный приложением, Manticore проверит и сохранит как есть; сервер не будет перестраивать его по собственной схеме.
Техническая деталь. Внешним идентификатором остаётся полный UUID: Manticore не заменяет его 64-битным хешем и не требует от приложения хранить таблицу соответствий. Как UUID устроен внутри движка — деталь реализации, на внешний контракт она никак не влияет.
Где это работает
UUID можно использовать как ID документа в обычных RT-таблицах, RT-таблицах с engine='columnar' и таблицах в кластере репликации. С такими ID доступны точный поиск, фильтр IN и привычные операции над документами: INSERT, REPLACE, UPDATE и DELETE.
Нужно учитывать ограничения:
- тип
uuidне подходит для обычных атрибутов: Manticore отклонит объявление вродеguid uuid; - в plain , percolate/PQ и shard-таблицах UUID нельзя использовать как ID документа;
- существующую таблицу нельзя переключить с числового ID на UUID или обратно через
ALTER TABLE; - диапазонные условия
<,<=,>и>=, а также арифметические операции с ID такого типа не поддерживаются; - ID документа нельзя изменить через
UPDATE— это относится и к UUID, и к числовым ID; - для автоматической генерации поле
idнужно опустить: значение0здесь не работает как специальный маркер.
Об этом легко забыть при переносе старого кода. Для числовой RT-таблицы 0 может означать «создать ID автоматически». В UUID-таблице поле id нужно просто не передавать.
UUIDv7 тоже не делает id пригодным для фильтров по времени. Его можно использовать как внешний идентификатор, но запросы вида id > ... Manticore пока не поддерживает.
Подведём итоги
Если UUID уже есть в основной БД, можете теперь передавать его в Manticore вместе с документом. Если документ сначала появляется в Manticore, не указывайте id и заберите сгенерированный UUID из ответа.
Дальше этот же UUID используйте в UPDATE, REPLACE и DELETE. Выдавать документу отдельный числовой ID и хранить соответствие между двумя идентификаторами больше не нужно.
Полный контракт и актуальные ограничения собраны в документации: UUID document IDs . Поддержка UUID как ID документа появилась в Manticore Search 28.5.0 .
В следующем материале — практическом руководстве по работе с UUID как ID документа — пошагово покажем, как через SQL и JSON задавать и генерировать ID, искать, обновлять, заменять и удалять документы, а также обрабатывать ошибки.
