POST /v1/namespaces/{ns}/search exécute jusqu’à trois branches classées sur un même ensemble de lignes filtré. Toutes les branches sont optionnelles ; au moins une est requise. label et filter s’appliquent à chaque branche.
Filtres
Deux formes sont acceptées :- Égalité simple :
{"property": "project", "value": "conare"}— servi directement depuis les posting lists. - DSL tableau :
[property, op, value]avecEq,NotEq,Gt,Gte,Lt,Lte,In(valeur tableau), composés avec["And", [f1, f2, ...]]/["Or", [...]]jusqu’à 16 niveaux.
false < true. Une incompatibilité de type ou une propriété absente ne correspond à rien — y compris pour NotEq — n’entraîne jamais d’erreur. Les opérateurs inconnus, les listes And/Or vides et les valeurs In non tabulaires renvoient un 400 en nommant le fautif.
Branche vectorielle
Les scores sont la similarité cosinus sur des vecteurs L2-normalisés, et toujours exacts — l’index ANN (IVF + codes RaBitQ 1-bit) présélectionne des candidats, puis les reclasse contre les vecteurs pleine précision. Options :
La recherche vectorielle filtrée renvoie exactement les résultats ANN sur le sous-ensemble correspondant — le moteur élargit le probing pour compenser la sélectivité, de sorte que les filtres ne vous coûtent pas silencieusement du rappel.
Déterminisme : pour un état d’index fixé, des octets de requête identiques avec des paramètres identiques renvoient des listes de hits identiques au bit près — à n’importe quel nombre de threads ou niveau de concurrence. En coulisses, un échantillonneur continu rejoue environ 1 % des requêtes ANN contre le ground truth brute-force et publie le rappel ; l’endpoint sans identifiants
GET /recall-slo rapporte la santé du rappel de la flotte.
Branche mots-clés
BM25 (k1=1.2, b=0.75) sur la propriété text. Tokenizer : minuscules, découpe à chaque caractère non alphanumérique — pas de stemming, pas de stopwords (parité de word-tokenizer avec Turbopuffer).
match contrôle la combinaison des tokens :
"auto"(défaut) — exige tous les tokens ; si cela renvoie moins demax(5, top_k/8)hits, réessaye en any-token. La réponse indique quel mode a été exécuté ("mode": "and"/"or")."all"— tous les tokens requis."any"— BM25 disjonctif ordinaire.
Branche chronologique
Classe par n’importe quelle propriété entière,asc ou desc — la branche « le plus récent d’abord » peu coûteuse d’une requête hybride.
Projection de propriétés
include_props contrôle ce qui accompagne chaque hit : omettez-le pour n’obtenir que id+score (aucun coût supplémentaire), passez un tableau de noms pour ne projeter que ces clés, ou true pour la carte de propriétés complète. La projection permet à un reranker de consommer les hits sans un second aller-retour de lookup.
Shim compatible Turbopuffer
POST /v2/namespaces/{ns}/query accepte la forme de lecture Turbopuffer — {rank_by, filters, top_k, include_attributes} — et renvoie {"rows": [{"id", "$dist", ...}]} avec $dist en distance cosinus. rank_by: ["id", "asc"] avec filters: ["id", "Gt", cursor] donne la pagination/export par curseur. Les formes non prises en charge donnent des 400 explicites nommant le champ — jamais une requête silencieusement différente.