Búsqueda Múltiple y Consultas
Ejecute múltiples consultas de búsqueda en una sola solicitud para autocompletado, búsqueda federada y escenarios de múltiples índices.
La búsqueda múltiple ejecuta múltiples consultas de búsqueda en un solo viaje de ida y vuelta HTTP. Esto es esencial para el autocompletado (ejecutar una consulta de resultados + una consulta de sugerencias simultáneamente) y la búsqueda federada (buscar en múltiples índices a la vez).
Endpoint de búsqueda múltiple
Endpoint: POST /api/search/multi
Autenticación: Authorization: Bearer ss_search_your_key
{
searches: Array<{
indexSlug: string;
q: string;
queryBy?: string;
filterBy?: string;
facetBy?: string;
sortBy?: string;
page?: number;
perPage?: number;
highlightFields?: string;
}>;
}Respuesta:
{
results: Array<SearchResponse>; // un resultado por búsqueda en el mismo orden
}Patrón de autocompletado
El caso de uso más común de búsqueda múltiple: ejecutar una búsqueda completa más una consulta de sugerencias rápidas simultáneamente.
const [mainResults, suggestions] = await client.multiSearch([
{
indexSlug: "products",
q: "auriculares inalám",
queryBy: "title,brand,description",
perPage: 20,
facetBy: "brand,categories",
},
{
indexSlug: "products",
q: "auriculares inalám",
queryBy: "title",
perPage: 5,
includeFields: "id,title",
highlightFields: "title",
},
]);Esto envía una sola solicitud HTTP y obtiene ambos conjuntos de resultados simultáneamente.
Búsqueda federada en índices
Busque en múltiples índices y combine los resultados en el cliente:
const [productResults, articleResults] = await client.multiSearch([
{
indexSlug: "products",
q: "sostenibilidad",
queryBy: "title,description,tags",
perPage: 10,
},
{
indexSlug: "knowledge",
q: "sostenibilidad",
queryBy: "content,title",
perPage: 5,
},
]);Nota: Para resultados entre índices, combine y reclasifique en el cliente.
Parámetros de consulta en profundidad
q — consulta de búsqueda
La cadena de búsqueda. Use "*" para una exploración comodín (sin coincidencia de texto completo, útil para exploración filtrada).
{ "q": "auriculares inalámbricos" } // búsqueda de texto completo
{ "q": "*" } // explorar todo (combinar con filterBy)queryBy — qué campos buscar
Lista separada por comas de campos. El orden importa — los campos anteriores obtienen mayor peso por defecto.
{ "queryBy": "title,sku,brand,description" }Para cada campo puede especificar un peso por campo:
{ "queryBy": "title,brand,description", "queryByWeights": "10,5,2" }filterBy — expresión de filtro
Expresión booleana usando la sintaxis de filtro de AACSearch:
Igualdad: field:=value
field:=[value1, value2]
Rango: field:>100
field:[50..200]
Cadena exacta: field:=value
Negación: field:!=value
AND lógico: cond1 && cond2
OR lógico: cond1 || cond2
Agrupación: (cond1 || cond2) && cond3Ejemplos:
"filterBy": "availability:=in_stock"
"filterBy": "price:[50..200] && brand:=[Sony, Bose]"
"filterBy": "categories:=Electrónica && availability:!=out_of_stock"facetBy — calcular recuentos de facetas
Devuelve distribuciones de valores para los campos especificados. Los campos de faceta deben estar indexados como facet: true
en el esquema de la colección.
{ "facetBy": "brand,categories,availability" }La respuesta incluirá facetCounts con pares valor → recuento para cada campo de faceta.
sortBy — orden de clasificación
Ordenación por un solo campo o múltiples campos:
{ "sortBy": "price:asc" }
{ "sortBy": "_text_match:desc,price:asc" }
{ "sortBy": "created_at:desc" }Campos de ordenación disponibles: price, sale_price, created_at, _text_match (puntuación de relevancia).
Tolerancia a errores tipográficos
La tolerancia a errores tipográficos de AACSearch se aplica automáticamente. Por defecto:
- Se permite 1 error tipográfico para consultas de 5+ caracteres
- Se permiten 2 errores tipográficos para consultas de 8+ caracteres
Esto maneja errores de escritura comunes como "auriculares" → coincide con "auriculares".
Resaltado
Los términos coincidentes se resaltan con etiquetas configurables:
{
"highlightFields": "title,description",
"highlightStartTag": "<em class='highlight'>",
"highlightEndTag": "</em>"
}Resaltados en la respuesta:
{
"highlights": [
{
"field": "title",
"snippet": "Sony <em class='highlight'>Auriculares</em> <em class='highlight'>Inalámbricos</em>"
}
]
}Paginación
Los resultados se paginan usando page (indexado desde 1) y perPage:
{ "page": 2, "perPage": 20 }La respuesta incluye found (recuento total coincidente) para calcular los totales de páginas:
const totalPages = Math.ceil(results.found / perPage);Máximo perPage: 100. Para exportaciones que requieren más resultados, implemente iteración basada en cursor
usando valores crecientes de page.
Recomendaciones de rendimiento
- Mantenga
perPage ≤ 20para búsqueda mientras se escribe (autocompletado) - Use
includeFieldspara devolver solo los campos que renderiza — reduce el tamaño de la respuesta - Evite ejecutar facetas en cada pulsación de tecla — elimine rebotes a 150–300 ms
- Para conjuntos de resultados grandes con muchas facetas, considere separar la consulta de facetas de la consulta principal usando búsqueda múltiple
Limits
| Limit | Value |
|---|---|
| Max searches per multi-search request | 20 — enforced in public-handler.ts. |
Max perPage | 100 |
Max page | 1000 |
Max numTypos | 3 |
Max rangeFacets per search | 20 |
Exceeding the multi-search batch limit returns 400 invalid_input with the Zod path searches. Use two consecutive requests rather than batching past 20.
Partial failures
A multi-search request is atomic at the HTTP level — sub-searches can still fail individually inside a 200. Each result envelope carries its own status: success carries hits, found, page; failure carries error and code. Iterate the results array in order; treat any entry with error as a sub-search failure. A single sub-search failure does not roll back the others.
Common error reasons: collection_not_found, invalid_filter, not_authorized (scoped token mismatch), rate_limit_exceeded, internal_error. Engine errors are normalised before reaching the client (Invariant 6 — never echoed raw).
Shared authentication and quota
Authentication is per request, not per sub-search. The same Authorization: Bearer ss_search_* (or ss_scoped_*) header validates the entire batch. A scoped token's scopedFilter is AND-combined into every sub-search (Invariant 4).
Quota / rate limit treats the batch as a single HTTP unit but charges per sub-search. A 20-batch is 20× the unit cost of a single search.
Tenant isolation (Invariant 5) holds at the sub-search level — every sub-search has tenantId AND-combined automatically.
Analytics grouping
Each multi-search response carries a parent queryId (the whole batch) and a per-sub-result queryId. Click events posted via POST /events/track should carry the child queryId so per-search CTR computes correctly. Conversion events follow the same rule. See Analytics overview.
A common bug is to record clicks against the first sub-search's queryId regardless of which list the click came from — that inflates the suggestions-list CTR and deflates the main-results CTR. Always pass through the specific child queryId.
Caching and debouncing
Recommended values (matching the bundled widget): keystroke debounce 200 ms (range 150–300 ms), min characters 2, client-side LRU 30 entries scoped to indexSlug, popular-queries TTL 10 min.
Do not extend the server-side response cache without a rate-limit-aware invalidation path — stale suggestions can keep linking to products that have been removed by a curation change.
Federated suggestions example
Combining a primary product search with a categories suggestion and an articles suggestion in one round-trip:
const [products, categories, articles] = await client.multiSearch([
{ indexSlug: "products", q: "wireless head", queryBy: "title,brand,description", perPage: 20, facetBy: "brand,categories" },
{ indexSlug: "categories", q: "wireless head", queryBy: "name,aliases", perPage: 3, includeFields: "id,name,slug" },
{ indexSlug: "articles", q: "wireless head", queryBy: "title,excerpt", perPage: 3, includeFields: "id,title,url,published_at" },
]);Three sub-searches still count as three units against the rate-limit bucket — budget accordingly.
Tokens de Búsqueda con Ámbito
Genere tokens HMAC de corta duración que reducen los permisos de una clave de búsqueda — filtros por usuario, TTL y modelo de seguridad.
Filtros, Ordenación y Paginación
Referencia completa para expresiones de filtro, opciones de ordenación, facetado y paginación en las consultas de AACsearch.