POST /v1/namespaces/{ns}/search виконує до трьох ранжованих гілок над одним фільтрованим набором рядків. Усі гілки опціональні; принаймні одна обов’язкова. label та filter застосовуються до кожної гілки.
Фільтри
Приймаються дві форми:- Одинична рівність:
{"property": "project", "value": "conare"}— обслуговується прямо з posting-list. - Масивний DSL:
[property, op, value]зEq,NotEq,Gt,Gte,Lt,Lte,In(значення-масив), скомпоновано через["And", [f1, f2, ...]]/["Or", [...]]до 16 рівнів.
false < true. Невідповідність типу або відсутня властивість нічого не відповідає — включно з NotEq — ніколи не помилка. Невідомі оператори, порожні списки And/Or та не-масивні значення In — 400 з іменем порушника.
Векторна гілка
Скори — cosine similarity на L2-нормалізованих векторах, і завжди точні — ANN-індекс (IVF + RaBitQ 1-bit коди) робить шортлист кандидатів, потім реранжує їх проти full-precision векторів. Опції:
Векторний пошук з фільтром повертає рівно результати ANN-на-збіжному-підмножині — двигун розширює probing, щоб компенсувати селективність, тож фільтри не забирають у вас recall непомітно.
Детермінізм: при фіксованому стані індексу ідентичні байти запиту з ідентичними параметрами повертають байт-ідентичні списки хітів — при будь-якій кількості потоків чи конкурентності. За лаштунками безперервний семплер відтворює ~1% ANN-запитів проти brute-force ground truth і публікує recall; endpoint
GET /recall-slo без credential’ів звітує про recall-здоров’я флоту.
Keyword-гілка
BM25 (k1=1.2, b=0.75) над властивістю text. Токенайзер: lowercase, розбиття за кожним не-alphanumeric символом — без стемінгу, без stopwords (word-tokenizer у паритеті з Turbopuffer).
match керує комбінацією токенів:
"auto"(default) — вимагати всі токени; якщо це дає менш ніжmax(5, top_k/8)хітів, повторити як any-token. Відповідь звітує, який режим виконався ("mode": "and"/"or")."all"— кожен токен обов’язковий."any"— звичайний диз’юнктивний BM25.
Хронологічна гілка
Ранжує за будь-якою цілочисельною властивістю,asc або desc — дешева гілка «найновіші перші» гібридного запиту.
Проекція властивостей
include_props керує тим, що їде разом із кожним хітом: пропустіть його для лише id+score (нульова додаткова вартість), передайте масив імен, щоб спроектувати лише ці ключі, або true для повної property-мапи. Проекція означає, що reranker може споживати хіти без другого lookup roundtrip.
Turbopuffer-сумісний shim
POST /v2/namespaces/{ns}/query приймає форму читання Turbopuffer — {rank_by, filters, top_k, include_attributes} — і повертає {"rows": [{"id", "$dist", ...}]} з $dist як cosine distance. rank_by: ["id", "asc"] з filters: ["id", "Gt", cursor] дає cursor-пагінацію/експорт. Непідтримувані форми — явні 400 з іменем поля — ніколи тихо-інший запит.