Skip to main content

Життєвий цикл рядка

Три види кроків покривають життєвий цикл за ключем-id, усі через POST /v1/namespaces/{ns}/query:
  • UpsertN — повна заміна рядка за зовнішнім id. Наявні рядки з цим id видаляються, потім вставляється новий. Заміна, не злиття: upsert без вектора над векторизованим рядком скидає вектор.
  • SetProps — перезаписує конкретні ключі у відповідному потоці (починайте запит з NWhere); значення null видаляє ключ. Сам id змінити не можна — це UpsertN. Підходить для нечастих переписувань атрибутів, не підходить для лічильників за кожен запит.
  • DeleteN — видаляє відповідний потік (NWhereDeleteN) або передайте ids для прямого видалення за зовнішнім id.

Кодування векторів

Для рядка — одне з двох wire-кодувань (відправляти обидва — це 400):
vector_b64 — це base64 вектора як little-endian f32 масив — приблизно у 4 рази менший на дроті і декодується memcpy замість парсингу чисел JSON. Кодер Python:
Обидва кодування дають бітово ідентичні збережені вектори та ідентичні результати пошуку. Розмірність фіксується першим векторизованим записом; невідповідність — це 400.

Масовий інджест: POST /v1/namespaces/{ns}/bulk-vectors

Високопропускний шлях засіву — один бінарний фрейм на запит (Content-Type: application/octet-stream): невеликий JSON-заголовок (dims, label, ids, спільні props), за яким ідуть значення L2-унормованого fp16 у row-major порядку. У порівнянні з JSON+base64, це уникає повторного кодування багатогігабайтних payload-ів кілька разів поспіль.

Restart-safe завантаження

Відновлювані завантажувачі передають ?expected_generation=<G>&expected_rows=<N>. Фрейм приймається лише коли простір імен саме в цьому стані:
  • Той самий фрейм уже комітнутий → 200 з "replayed": true і відповідним request_fingerprint — жодних дублювань рядків.
  • Інший payload на тій самій позиції → 409 write_conflict.
  • Успішні умовні записи повертають request_fingerprint, rows_before, rows_after — робіть чекпоінт свого батчу лише після отримання однієї з цих квитанцій.
Це робить «краш, рестарт, повторна відправка» цілісною історією відновлення: жодних імпорт-джобів, які треба доглядати.

Компакція

Автокомпакція геометрична, тож загальна робота компакції залишається лінійною за прийнятими байтами. Завершіть будь-яке масове завантаження явною компакцією — надішліть "compact": true на верхньому рівні останнього запиту запису:
Відповідь повідомляє "compacted": true/false. Компакція також будує ANN-індекс, коли таблиця стає достатньо великою; рядки, записані після знімка індексу, brute-force вливаються в результати, тож свіжістю ніколи не жертвують.

Дедуплікація масового джерела

Масові фрейми за задумом дописують сліпо — джерело з дублікатами id тихо їх приземляє, а дублікати спалюють слоти top-k. {"DedupN": {}} узгоджує сховище з контрактом унікальності зовнішніх id (зберігає останній записаний рядок на id), а {"DedupN": {"dry_run": true}} — це аудит-перепис лише для census, який будь-яке масове завантаження має запускати, коли його джерело не може довести унікальність id — збіжна загальна кількість рядків не може розкрити дублікати, що ховаються всередині.

Правила ретраїв

Читання завжди можна повторити після транспортного збою. Для записів автоматично ретраїзуються лише умовні bulk-фрейми (ідентичний фрейм + параметри CAS → оригінальна квитанція або replayed: true). Ніколи сліпо не переграйте безумовний запис після втраченої відповіді — спершу узгодьте стан.