De la recuperación a resultados estructurados: agregación y ORDER BY en Milvus 3.0
Considere un flujo familiar de búsqueda de productos. Un comprador sube una foto de un vestido, y la búsqueda vectorial recupera un conjunto de candidatos relevante de un catálogo que contiene decenas de millones de productos.
La página, sin embargo, necesita más que una lista clasificada. Necesita facetas de marca. Necesita una ordenación por precio. El equipo de merchandising quiere saber qué marcas dominan este conjunto de resultados, el rango de precios dentro de cada marca y algunos productos representativos de cada grupo.
Antes de Milvus 3.0, las aplicaciones solían encargarse ellas mismas de ese segundo paso: recuperar filas de Milvus, agruparlas y ordenarlas en pandas o en una capa de servicio, y luego ensamblar la respuesta. Algunos equipos mantenían una canalización de analítica independiente únicamente para calcular recuentos y distribuciones sobre datos que ya estaban en la base de datos vectorial.
La base de datos vectorial encontraba los candidatos; la aplicación tenía que convertirlos en un resultado estructurado.
Milvus 3.0 traslada más de ese trabajo al motor de recuperación. Añade tres capacidades relacionadas pero distintas:
- La agregación de consultas calcula
count,sum,avg,minymaxsobre filas filtradas y visibles, con camposGROUP BYopcionales. - Search Aggregation organiza los candidatos de vecinos más cercanos aproximados (ANN) retenidos en buckets, calcula métricas por bucket, crea buckets anidados y devuelve resultados representativos.
- El lado del servidor
**ORDER BY**ordena los resultados de consulta o los candidatos ANN por uno o más campos escalares antes de que la aplicación los reciba.
La distinción entre consulta y búsqueda importa:
| Capacidad | Datos que se resumen u ordenan | Forma principal del resultado | Límite de exactitud |
|---|---|---|---|
| Agregación de consultas | Todas las filas visibles que coinciden con el filtro | Una fila por grupo, con valores agregados | Exacta sobre el conjunto de filas visibles de la consulta |
| Search Aggregation | Candidatos retenidos por la búsqueda ANN y la etapa de agrupación | Buckets, métricas, resultados representativos y buckets secundarios opcionales | Aproximada por diseño |
Consulta ORDER BY | Filas visibles que coinciden con el filtro | Filas ordenadas | Exacta sobre el resultado de consulta filtrado |
Búsqueda ORDER BY | Candidatos ANN | Resultados de búsqueda o grupos ordenados | No amplía el límite de recuperación ANN |
Este artículo explica por qué estas operaciones pertenecen dentro de la base de datos, cómo funciona la agregación distribuida, en qué se diferencia Search Aggregation de Grouping Search y dónde terminan las nuevas semánticas.
Por qué el posprocesamiento del lado de la aplicación deja de funcionar
Mover la agregación y la ordenación a la aplicación puede parecer una pequeña decisión de implementación. A escala, crea tres problemas mayores.
La aplicación mueve muchos más datos de los que contiene la respuesta
Supongamos que un panel de operaciones necesita el recuento de productos y el precio medio de cada categoría entre dos millones de filas con stock. Incluso con una carga útil aproximada de solo 100 bytes por fila para la categoría, el precio, la clave primaria y la sobrecarga de serialización, la aplicación debe recibir unos 200 MB de datos antes de poder calcular el resultado.
Si el catálogo tiene 200 categorías, la respuesta son solo unos pocos cientos de claves y números: del orden de kilobytes. La aplicación mueve varios órdenes de magnitud más datos de los que devuelve, paga el mismo coste en cada actualización y necesita suficiente memoria de cliente para mantener o transmitir las filas intermedias.
Una agregación dentro del motor cambia la unidad de movimiento de datos. Las filas sin procesar permanecen donde están. Lo que cruza nodos y finalmente sale de Milvus es el conjunto mucho más pequeño de estados de grupo parciales y finales.
La ordenación local de una página no es ordenación global
Ordenar después de paginar es un error de corrección, no simplemente una implementación ineficiente.
Si una aplicación obtiene las filas 11 a 20 y ordena solo esas filas por precio, ha producido el orden de precios dentro de esa página, no las filas 11 a 20 del resultado global ordenado por precio. Una página posterior puede contener productos más baratos que todos los productos de la primera página.
El mismo límite importa en la búsqueda vectorial. Obtener un conjunto Top-K pequeño y ordenarlo en la aplicación solo puede reordenar esos candidatos. No puede recuperar candidatos relevantes que la etapa ANN no devolvió, y a menudo lleva a las aplicaciones a sobrerrecuperar solo para que la ordenación del lado del cliente sea útil.
La ordenación del lado del servidor da a Milvus control sobre la secuencia de ordenación y paginación. Para cargas de trabajo de consulta, el motor ordena el conjunto de filas filtradas antes de aplicar la ventana de página. Para cargas de trabajo de búsqueda, ordena dentro del límite de candidatos ANN y mantiene explícita esa limitación.
El cliente no puede reproducir la visibilidad de la base de datos
La agregación también depende de qué filas son visibles en la marca de tiempo de la consulta. Las eliminaciones, las entidades expiradas y las escrituras concurrentes se rigen por el control de concurrencia multiversión (MVCC) de Milvus y sus semánticas de consistencia.
Una vez que las filas sin procesar salen de la base de datos, la aplicación suele asumir que el lote recibido representa la instantánea correcta. Reconstruir las mismas reglas de visibilidad en un cliente es impracticable, especialmente mientras la colección recibe escrituras y eliminaciones.
La solución alternativa habitual —un segundo motor de analítica alimentado por exportación y ETL— añade otra copia de los datos, otro límite de consistencia y otra canalización que operar. Los recuentos, las métricas y la ordenación deben ejecutarse donde ya existen tanto los datos como sus reglas de visibilidad.
Ahora, veamos qué ofrece Milvus 3.0.
Agregación de consultas: estadísticas exactas sobre filas visibles
La agregación de consultas responde preguntas como:
- ¿Cuántos productos con stock hay en cada categoría?
- ¿Cuál es el precio medio por marca?
- ¿Cuáles son las marcas de tiempo de evento mínima y máxima para cada host?
- ¿Cuántos registros permanecen después de aplicar un filtro y la visibilidad TTL?
La API resulta familiar para cualquiera que haya usado SQL: pase uno o más campos en group_by_fields y luego coloque expresiones de agregación en output_fields.
res = client.query(
collection_name="products",
filter='status == "on_sale"',
group_by_fields=["category"],
output_fields=["category", "count(*)", "avg(price)"],
)
# [
# {"category": "books", "count(*)": 18734, "avg(price)": 45.3},
# …
# ]
La sintaxis es la parte sencilla. El modelo de ejecución es lo que hace que el resultado sea útil en una base de datos vectorial distribuida.
Los estados locales de segmento sustituyen el movimiento de filas sin procesar
Una colección de Milvus puede abarcar cientos o miles de segmentos distribuidos entre varios nodos de consulta, con datos escritos recientemente todavía en la ruta de streaming. Ningún nodo de ejecución individual comienza con todas las filas visibles.
Por lo tanto, Milvus empuja la agregación hacia los segmentos:
- Cada segmento aplica localmente el filtro y las reglas de visibilidad MVCC.
- El segmento emite un estado parcial por grupo en lugar de sus filas coincidentes.
- Los estados parciales se fusionan dentro de un nodo de consulta.
- El proxy realiza la fusión final entre nodos y devuelve los grupos completos.
La cantidad de datos intermedios ahora escala con el número de grupos y estados agregados, en lugar de escalar directamente con el número de filas coincidentes.
La operación de fusión depende del agregado:
| Agregado | Estado parcial | Regla de fusión |
|---|---|---|
count | Recuento parcial | Sumar recuentos |
sum | Suma parcial | Sumar sumas |
min | Mínimo parcial | Tomar el mínimo |
max | Máximo parcial | Tomar el máximo |
avg | Suma y recuento parciales | Sumar ambos estados y luego dividir una vez en la etapa final |
avg es el caso ilustrativo. Promediar dos promedios parciales es incorrecto cuando las particiones contienen distintos números de filas. Milvus lleva sum y count de forma independiente y calcula el promedio final solo después de que ambos se hayan fusionado globalmente.
Esta es una razón por la que la agregación pertenece a la base de datos: la operación no consiste simplemente en “ejecutar la misma función sobre varios lotes”. El motor debe preservar el álgebra de cada agregado a través de los límites de segmentos y nodos.
La visibilidad se aplica antes de la agregación
Las filas eliminadas y expiradas se eliminan de los estados parciales a nivel de segmento según el límite de visibilidad de la consulta. No viajan hacia arriba para luego corregirse en la aplicación.
Por lo tanto, el resultado describe las filas que Milvus considera visibles para esa solicitud, no una colección arbitraria de lotes extraídos en momentos ligeramente distintos.
limit ahora cuenta grupos
En una consulta normal, limit controla cuántas filas de entidad se devuelven. En una consulta agrupada, controla cuántos grupos se devuelven. Como la cardinalidad del resultado está determinada por los grupos y no por las filas coincidentes, una agregación de consulta también puede omitir limit cuando necesita todos los grupos.
Esto suena como un pequeño detalle de API, pero refleja un modelo de resultados diferente: la salida ya no es una página de entidades. Es una relación cuyas filas representan grupos.
Search Aggregation: una vista en buckets de candidatos ANN
La agregación de consultas responde: “¿Qué aspecto tienen las filas visibles que coinciden con este filtro?”. Search Aggregation plantea una pregunta diferente: “¿Qué aspecto tiene el conjunto de candidatos recuperado para este vector?”.
Esa operación no tiene un equivalente SQL exacto. La búsqueda ANN primero establece un límite de candidatos impulsado por similitud. Luego Milvus organiza los candidatos retenidos por claves escalares y devuelve un árbol de buckets en lugar de una lista plana ordinaria de resultados.
Un bucket puede contener:
- una clave como
brando una clave compuesta como(brand, color); - un recuento de candidatos retenidos;
- métricas que incluyen
count,sum,avg,minymax; - entidades representativas seleccionadas con
top_hits; y - una
sub_aggregationanidada que crea buckets secundarios.
Para la página de búsqueda de productos, una solicitud puede devolver buckets de marca, el precio medio dentro de cada bucket y tres productos representativos por marca:
from pymilvus import SearchAggregation, TopHits
aggregation = SearchAggregation(
fields=[“brand”],
size=10, # Return up to 10 brand buckets
metrics={“avg_price”: {“avg”: “price”}},
order=[{“_count”: “desc”}], # Order by retained-candidate count
top_hits=TopHits(
size=3,
sort=[{“_score”: “desc”}], # Use “asc” for L2 distance
),
)
res = client.search(
collection_name=“products”,
data=[query_vector],
anns_field=“embedding”,
search_aggregation=aggregation,
output_fields=[“title”, “brand”, “price”],
)
buckets = res.agg_buckets[0]
Cuando search_aggregation está establecido, la lista ordinaria de resultados está vacía. La aplicación lee la respuesta de buckets desde result.agg_buckets.
La especificación de agregación establece dos límites diferentes
Search Aggregation no ejecuta GROUP BY sobre cada entidad de la colección, y tampoco toma simplemente una respuesta Top-K ordinaria para agregar esa lista plana.
Su ejecución tiene tres etapas:
- Milvus ejecuta una búsqueda ANN para recuperar candidatos cercanos al vector de consulta.
- La etapa de agrupación retiene un número acotado de candidatos para cada clave de bucket completa.
- Milvus crea buckets, calcula métricas sobre los candidatos retenidos, ordena los buckets y adjunta resultados representativos o buckets secundarios.
Dos parámetros controlan partes distintas del resultado:
SearchAggregation.sizelimita cuántos buckets se devuelven en ese nivel de agregación.- El mayor
TopHits.sizeen cualquier lugar del árbol de agregación establece el presupuesto de candidatos retenidos para cada clave compuesta completa. Si la solicitud no contienetop_hits, el presupuesto por clave toma el valor predeterminado de uno.
El limit de búsqueda de nivel superior no controla este modo y se ignora cuando search_aggregation está presente.
Esa distinción es esencial al leer el count o las métricas de un bucket. Con TopHits(size=3), un bucket de marca puede resumir como máximo tres candidatos retenidos para su clave completa, incluso si la colección contiene miles de productos relevantes de esa marca. Aumentar TopHits.size amplía la ventana de métricas por clave, pero no convierte la búsqueda ANN en un escaneo exacto.
Si la aplicación necesita estadísticas exactas sobre cada fila visible que coincide con un filtro, debe usar la agregación de consultas. Search Aggregation sirve para describir y comparar los candidatos producidos por la recuperación por similitud.
Search Aggregation y Grouping Search resuelven problemas diferentes
Milvus admite Grouping Search (group_by)desde Milvus 2.4. Es fácil ver la palabra “grouping” en ambas funciones y asumir que son dos interfaces para la misma operación. Sus contratos de salida son diferentes.
Grouping Search cambia qué entidades aparecen en una lista de resultados clasificada. Un patrón RAG común almacena fragmentos como entidades individuales, los agrupa por doc_id y devuelve uno o algunos fragmentos de cada documento. La salida principal sigue siendo resultados de búsqueda ordinarios, pero con menos valores repetidos del campo de agrupación.
Search Aggregation devuelve una vista estadística. La salida principal es un árbol de buckets que contiene claves, recuentos, métricas, resultados representativos y buckets secundarios opcionales.
| Necesidad de la aplicación | Preferir | Consumir |
|---|---|---|
| Una lista de entidades clasificada con mayor diversidad en un campo | Grouping Search | Resultados de búsqueda ordinarios |
| Recuentos de facetas, métricas por grupo, resultados representativos o distribuciones anidadas | Search Aggregation | Objetos AggregationBucket en result.agg_buckets |
Una regla práctica es comenzar por la forma de la respuesta de la UI o la API. Si la aplicación renderiza una lista, Grouping Search suele ser la primitiva adecuada. Si renderiza facetas, tarjetas de distribución o una jerarquía de grupos, use Search Aggregation.
Los dos modos son mutuamente excluyentes en una solicitud porque definen formas de resultado principales diferentes.
ORDER BY: mover la ordenación antes del límite de la aplicación
La ordenación es la función menos exótica de esta versión y una de las más fáciles de implementar incorrectamente fuera del motor.
Milvus 3.0 expone la ordenación tanto en consulta como en búsqueda, pero las dos rutas usan parámetros de SDK diferentes y operan sobre conjuntos de entrada distintos.
La ordenación de consultas ordena el conjunto de filas filtradas
La consulta de PyMilvus usa order_by, expresado como una lista de cadenas "field:direction". El motor aplica el filtro, ordena las filas visibles y luego aplica limit y offset.
res = client.query(
collection_name="products",
filter='category == "books"',
output_fields=["title", "price"],
order_by=["price:desc", "title:asc"],
limit=10,
offset=10, # Rows 11-20 in the filtered, price-sorted result
)
Esto hace que la consulta sea útil para la navegación ordenada por criterios de negocio: registros ingeridos más recientes, productos de mayor precio dentro de un filtro, menor inventario o valores extremos para inspección de datos. Sin ordenación del lado del servidor, las aplicaciones tenían que recuperar filas primero y no podían definir un orden de negocio fiable entre páginas.
Para campos de consulta anulables, el orden ascendente coloca los nulos al final y el orden descendente los coloca al principio. Un campo de ordenación no tiene que aparecer en output_fields; inclúyalo solo cuando la aplicación necesite el valor en la respuesta.
La ordenación de búsqueda reordena el conjunto de candidatos ANN
La búsqueda de PyMilvus usa order_by_fields, donde cada entrada nombra un campo escalar y una dirección:
res = client.search(
collection_name="products",
data=[query_vector],
anns_field="embedding",
limit=50,
output_fields=["title", "price"],
order_by_fields=[
{"field": "price", "order": "asc"},
],
)
ANN sigue determinando qué entidades se convierten en candidatos. order_by_fields cambia cómo se devuelven esos candidatos; no hace que la búsqueda escanee globalmente la colección para encontrar los productos más baratos.
Ese límite da a las dos API trabajos distintos:
- Use consulta más
order_bycuando el orden escalar en sí define el resultado, como los diez productos con stock más baratos. - Use búsqueda más
order_by_fieldscuando la relevancia semántica o vectorial define el conjunto de candidatos y un campo escalar determina cómo deben presentarse esos candidatos.
La ordenación por varios campos aplica las claves en el orden de la lista. Cuando los candidatos de búsqueda tienen los mismos valores para cada clave escalar especificada, Milvus conserva su orden original por puntuación de similitud.
La ordenación también se compone con Grouping Search. Milvus ordena los grupos por el valor escalar configurado de la entidad principal de cada grupo, conservando la forma de resultado agrupado. Esto es útil cuando la aplicación quiere tanto diversidad entre un campo como un orden de grupo relevante para el negocio.
Qué hacen posibles estas capacidades
Las API son primitivas generales de base de datos, pero varias cargas de trabajo de recuperación se benefician de inmediato.
RAG y agentes: inspeccionar la concentración de la recuperación
Un sistema RAG o agéntico puede agrupar en buckets los fragmentos recuperados por documento de origen, línea de producto, tenant o tipo de contenido. Un resultado concentrado en dos documentos transmite una señal de cobertura distinta a la de uno distribuido entre decenas de fuentes.
Esa distribución no es una garantía de calidad de la respuesta. Sin embargo, es un diagnóstico de recuperación útil que una aplicación o agente puede combinar con puntuaciones, citas y otras comprobaciones al decidir si ampliar la consulta, recuperar de nuevo o pedir aclaración.
Grouping Search sigue siendo la opción adecuada cuando el objetivo es simplemente diversificar los fragmentos devueltos. Search Aggregation es útil cuando el sistema necesita la distribución en sí.
Comercio electrónico y recomendación de contenido: devolver facetas con la búsqueda
La página inicial de búsqueda de productos puede recibir de Milvus buckets de marca, métricas de precio, artículos representativos y una lista de candidatos ordenada por escalares. La aplicación sigue controlando la presentación y la lógica de negocio, pero ya no necesita reconstruir semánticas básicas de buckets a partir de resultados exportados.
Registros y seguridad: combinar similitud con distribución de incidentes
La búsqueda por similitud puede encontrar eventos relacionados con una línea de registro sospechosa. Search Aggregation puede entonces mostrar qué hosts dominan esos candidatos, la marca de tiempo mínima y máxima en cada bucket de host, o cómo se dividen los candidatos por severidad y servicio.
El resultado sigue siendo una vista de candidatos recuperados, no un recuento global exacto de incidentes. Cuando la investigación necesita recuentos exactos sobre cada evento que coincide con un filtro, la agregación de consultas proporciona esa segunda ruta.
Operaciones y exploración de datos: calcular en lugar de exportar
Los paneles y las herramientas administrativas pueden ejecutar recuentos y promedios exactos sobre filas filtradas, y luego explorar las entidades subyacentes en un orden escalar definido. Eso elimina muchas utilidades puntuales de “exportar, calcular y ordenar” sin pretender que Milvus se haya convertido en una base de datos analítica completa.
Límites: lo que la agregación y ORDER BY no reemplazan
Estas funciones amplían el motor de recuperación; no convierten Milvus en un sistema de procesamiento analítico en línea (OLAP).
- La agregación de consultas admite agrupación más
count,sum,avg,minymax. No añade joins, funciones de ventana ni subconsultas complejas. Los trabajos analíticos offline de gran tamaño siguen perteneciendo a sistemas como Spark, que pueden trabajar con instantáneas de Milvus 3.0 y rutas de almacenamiento compartidas. - Las claves de grupo de consulta admiten campos enteros,
VARCHARyTIMESTAMPTZ. Las claves de bucket de Search Aggregation admiten además campos booleanos. Los valores de punto flotante, vector, JSON y array no son claves de bucket. - Para Search Aggregation,
countacepta"*"o una fuente no JSON y no dinámica;sumyavgrequieren fuentes numéricas; yminymaxtambién admiten fuentes de cadena yTIMESTAMPTZ. La agregación de consultas sigue los mismos límites de tipos aritméticos. Consulte la guía de la API antes de aplicar un agregado a un tipo de campo complejo. - La agregación de consultas puede ordenar la salida agrupada por claves de grupo, mientras que ordenar por un agregado calculado como
count(*)sigue siendo un límite actual. Sin un orden explícito, el orden de los grupos no está garantizado. - Search Aggregation no puede combinarse actualmente con Hybrid Search, Grouping Search, Search Iterators, un desplazamiento distinto de cero o resaltado en la misma solicitud.
- Los recuentos y las métricas de Search Aggregation describen candidatos ANN retenidos, no la colección completa ni cada entidad que podría ser semánticamente relevante.
- La búsqueda
ORDER BYcambia la presentación de candidatos. No repara candidatos ANN omitidos ni convierte la recuperación por similitud en una consulta escalar Top-N exacta.
La forma más clara de elegir entre las nuevas primitivas es empezar por la pregunta:
- Para estadísticas exactas sobre filas visibles filtradas, use la agregación de consultas.
- Para una distribución sobre candidatos de recuperación por similitud, use Search Aggregation.
- Para una lista clasificada diversa, use Grouping Search.
- Para un orden escalar definido, use consulta o búsqueda
ORDER BYsegún qué ruta haya establecido el conjunto de resultados.
De listas de candidatos a resultados estructurados
Las bases de datos vectoriales han optimizado tradicionalmente una pregunta: ¿qué K entidades están más cerca de este vector?
Los sistemas de recuperación de producción hacen preguntas de seguimiento de inmediato. ¿Qué grupos dominan el resultado? ¿Cuáles son sus recuentos y rangos? ¿Qué ejemplos representan a cada grupo? ¿En qué orden de negocio debe la aplicación presentar las filas o los candidatos?
Milvus 3.0 incorpora esas operaciones al mismo motor que posee los datos, el límite de candidatos ANN y las semánticas de visibilidad. La agregación de consultas realiza una reducción distribuida exacta sobre filas visibles. Search Aggregation crea una vista en buckets sobre candidatos ANN retenidos. ORDER BY da a las rutas de consulta y búsqueda un orden escalar del lado del servidor sin pedir a la aplicación que lo reconstruya página por página.
El resultado no es un motor OLAP oculto dentro de una base de datos vectorial. Es un motor de recuperación que puede devolver más de la estructura que las aplicaciones realmente necesitan.
Pruebe la agregación y ORDER BY en Milvus 3.0
Milvus 3.0 ya está disponible. Use la guía de consultas para agregación exacta y ordenación de consultas, la guía de Search Aggregation para semánticas y límites de buckets, la guía de búsqueda vectorial básica para ordenación de búsqueda, y la guía de Grouping Search cuando su objetivo principal sea la diversidad de resultados.
Para la versión más amplia, consulte el blog de lanzamiento de Milvus 3.0, las notas de la versión de Milvus 3.0 y el repositorio milvus-io/milvus.
Si desea evaluar las mismas API sin operar usted mismo el clúster, pruébelas en Zilliz Cloud. La referencia actual de consultas de Zilliz Cloud y la referencia de búsqueda describen la disponibilidad y los parámetros para tipos de clúster gestionados.
Para hablar con el equipo sobre una carga de trabajo o un caso límite, únase a la comunidad de Milvus en Discord o reserve una sesión de Milvus Office Hours.
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



