$rankFusion y $scoreFusion etapas están disponibles como funciones de vista previa. Para obtener más información, consulte Características de vista previa.Importante
$rankFusion solo está disponible para implementaciones que utilizan MongoDB 8.0 o superior.
Definición
$rankFusion$rankFusionPrimero ejecuta todas las canalizaciones de entrada de forma independiente y luego desduplica y combina los resultados de las canalizaciones de entrada en un conjunto de resultados clasificados finales.$rankFusionGenera un conjunto de documentos clasificados según la clasificación de los documentos de entrada en sus canales de entrada y sus ponderaciones. Esta etapa utiliza el algoritmo de Fusión de Rango Recíproco para clasificar los resultados combinados de los canales de entrada.Utilice
$rankFusionpara buscar documentos en una sola colección según múltiples criterios y recuperar un conjunto de resultados final clasificado que tenga en cuenta todos los criterios especificados.
Sintaxis
La etapa tiene la siguiente sintaxis:
{ $rankFusion: { input: { pipelines: { <myPipeline1>: <expression>, <myPipeline2>: <expression>, ... } }, combination: { weights: { <myPipeline1>: <numeric expression>, <myPipeline2>: <numeric expression>, ... } }, scoreDetails: <bool> } }
Campos de comandos
$rankFusion toma los siguientes campos:
Campo | Tipo | Descripción |
|---|---|---|
| Objeto | Define la entrada que clasifica |
input.pipelines | Objeto | Contiene un mapa de nombres de canalización con las etapas de agregación que la definen. Para obtener más información sobre las restricciones de la canalización de entrada, consulte Canalizaciones de entrada y nombres de canalizaciones de entrada. |
| Objeto | Opcional. Define cómo combinar los resultados del pipeline |
combination.weights | Objeto | Opcional. Contiene un mapa de los nombres de canalización Si no especifica un peso, el valor predeterminado es 1. |
| Booleano | El valor predeterminado es falso. Especifica si |
Comportamiento
Colecciones
Solo se puede usar $rankFusion con una sola colección. No se puede usar esta etapa de agregación en el ámbito de una base de datos.
De-Duplication
$rankFusion Desduplica los resultados de múltiples canales de entrada en la salida final. Cada documento de entrada único aparece como máximo una vez en la salida $rankFusion, independientemente del número de veces que aparezca en las salidas del canal de entrada.
Tuberías de entrada
Cada canalización input debe ser tanto una canalización de selección como una canalización clasificada.
Canal de selección
Una canalización de selección recupera un conjunto de documentos de una colección sin realizar ninguna modificación después de la recuperación. $rankFusion compara documentos en diferentes canalizaciones de entrada, lo que requiere que todas las canalizaciones de entrada generen los mismos documentos sin modificar.
Nota
Si desea modificar los documentos que busca con $rankFusion, realice esas modificaciones después de la etapa $rankFusion.
Una secuencia de selección solo debe contener las siguientes etapas:
Tipo | Etapas |
|---|---|
Etapas de búsqueda |
Si utiliza |
Etapas de ordenamiento | |
Etapas de paginación |
Pipeline clasificado
Una canalización clasificada ordena los documentos. $rankFusion utiliza el orden de los resultados de la canalización clasificada para influir en la clasificación de los resultados. Las canalizaciones clasificadas deben cumplir uno de los siguientes criterios:
Comience con una de las siguientes etapas ordenadas:
Contiene una etapa
$sortexplícita.
Nombres de canalizaciones de entrada
Los nombres de canalización en input deben cumplir las siguientes restricciones:
No debe ser una cadena vacía
No debe comenzar con una
$No debe contener el delimitador de carácter nulo ASCII
\0en ninguna parte de la cadenaNo debe contener una
.
Fórmula de fusión de rangos recíprocos (RRF)
$rankFusion Los resultados se ordenan según la Fórmula de Fusión de Rangos Recíprocos (RRF). Esta etapa coloca la puntuación RRF de cada documento en el campo de metadatos score de los resultados. La fórmula RRF clasifica los documentos mediante una combinación de los siguientes factores:
La colocación de documentos en los resultados de la tubería de entrada
La cantidad de veces que un documento aparece en diferentes canales de entrada
El
weightsde las canalizaciones de entrada.
Por ejemplo, si un documento tiene una clasificación alta en varios conjuntos de resultados de canalización, el puntaje RRF para ese documento sería más alto que si ese mismo documento tiene la misma clasificación en algunas canalizaciones de entrada, pero no está presente (o tiene una clasificación más baja) en las otras canalizaciones.
La fórmula de fusión de rangos recíprocos (RRF) es equivalente a la siguiente operación algebraica:

Nota
En esta fórmula, 60 es un parámetro de sensibilidad que determinó MongoDB.
La siguiente tabla contiene las variables que utiliza la fórmula RRF:
Variable | Descripción |
|---|---|
D | El conjunto de documentos de resultados de toda la operación. |
d | El documento para el cual se calcula la puntuación RRF. |
R | El conjunto de rangos para las canalizaciones de entrada en las que aparece |
r(d) | El rango del documento |
w | El peso de la tubería de entrada en la que aparece |
Cada término en la suma representa la aparición de un documento d en uno de los input pipelines. La puntuación total RRF para d es la suma de cada uno de estos términos en todos los pipelines de entrada en los que aparece d.
Ejemplo de cálculo de RRF
Considere una etapa de canalización $rankFusion con una canalización de entrada $search y una $vectorSearch.
Todas las canalizaciones de entrada generan los mismos documentos 3: Document1, Document2 y Document3.
La canalización $search clasifica los documentos en el siguiente orden:
Document3Document2Document1
La canalización $vectorSearch clasifica los documentos en el siguiente orden:
Document1Document2Document3.
rankFusion calcula la puntuación RRF para Document1 mediante la siguiente operación:
RRFscore(Document1) = 1/(60 + search_rank_of_Document1) + (1/(60 + vectorSearch_rank_of_Document1)) RRFscore(Document1) = 1/63 + 1/61 RRFscore(Document1) = 0.0322664585
El campo de metadatos score para Document1 es 0.0322664585.
Detalles de la puntuación
Si establece scoreDetails en true, $rankFusion crea un campo de metadatos scoreDetails para cada documento. El campo scoreDetails contiene información sobre la clasificación final.
Nota
Cuando se establece scoreDetails en true, $rankFusion establece el campo de metadatos scoreDetails para cada documento, pero no genera automáticamente el metacampo scoreDetails.
Para ver el campo de metadatos scoreDetails, debe:
Utilice una etapa
$projectdespués$rankFusionde para proyectar elscoreDetailscampoUtilice una etapa
$addFieldsdespués$rankFusionde para agregar elscoreDetailscampo a la salida de su canalización
El campo scoreDetails contiene los siguientes subcampos:
Campo | Descripción |
|---|---|
| El valor numérico de la PuntuaciónRRF para este documento. |
| Una descripción de cómo |
| Una matriz donde cada entrada de la matriz contiene información sobre las tuberías de entrada que generan este documento. |
Cada entrada de la matriz en el campo details contiene los siguientes subcampos:
Campo | Descripción |
|---|---|
| El nombre de la canalización de entrada que genera este documento. |
| El rango de este documento en la canalización de entrada. El rango es |
| El peso de la tubería de entrada. |
| Opcional. Si la canalización de entrada genera un |
| Opcional. Si la canalización de entrada genera un campo |
| El campo |
Advertencia
MongoDB no garantiza ningún formato de salida específico para scoreDetails.
Por ejemplo, los siguientes bloques de código muestran el campo scoreDetails para una operación $rankFusion con canales de entrada $search, $vectorSearch y $match:
{ value: 0.030621785881252923, description: "value output by reciprocal rank fusion algorithm, computed as sum of weight * (1 / (60 + rank)) across input pipelines from which this document is output, from:" details: [ { inputPipelineName: 'search', rank: 2, weight: 1, value: 0.3876491287, description: "sum of:", details: [... omitted for brevity in this example ...] }, { inputPipelineName: 'vector', rank: 9, weight: 3, value: 0.7793490886688232, details: [ ] }, { inputPipelineName: 'match', rank: 10, weight: 1, details: [] } ] }
Explique los resultados
MongoDB convierte las operaciones $rankFusion en un conjunto de etapas de agregación existentes que, en combinación, computan el resultado de salida antes de la ejecución de la query. La Explicación de resultados para una operación $rankFusion muestran la ejecución completa de las etapas de agregación subyacentes que $rankFusion utiliza para componer el resultado final.
Ejemplos
Este ejemplo utiliza una colección con incrustaciones y campos de texto. Cree índices de tipo search y vectorSearch en la colección.
La siguiente definición de índice indexa automáticamente todos los campos indexables dinámicamente en la colección para ejecutar consultas contra los campos $search indexados.
db.embedded_movies.createSearchIndex( "search_index", { mappings: { dynamic: true } } )
La siguiente definición de índice indexa el campo con las incrustaciones en la colección para ejecutar $vectorSearch consultas en ese campo.
db.embedded_movies.createSearchIndex( "vector_index", "vectorSearch", { "fields": [ { "type": "vector", "path": "<FIELD_NAME>", "numDimensions": <NUMBER_OF_DIMENSIONS>, "similarity": "dotProduct" } ] } );
La siguiente canalización de agregación utiliza $rankFusion con las siguientes canalizaciones de entrada:
Tubería | Número de documentos devueltos | Descripción |
|---|---|---|
| 20 | Ejecuta una búsqueda vectorial en el campo indexado como tipo |
| 20 | Ejecuta una búsqueda de texto completo para el mismo término y limita los resultados a 20 documentos. |
1 db.embedded_movies.aggregate( [ 2 { 3 $rankFusion: { 4 input: { 5 pipelines: { 6 searchOne: [ 7 { 8 "$vectorSearch": { 9 "index": "<INDEX_NAME>", 10 "path": "<FIELD_NAME>", 11 "queryVector": <QUERY_EMBEDDINGS>, 12 "numCandidates": 500, 13 "limit": 20 14 } 15 } 16 ], 17 searchTwo: [ 18 { 19 "$search": { 20 "index": "<INDEX_NAME>", 21 "text": { 22 "query": "<QUERY_TERM>", 23 "path": "<FIELD_NAME>" 24 } 25 } 26 }, 27 { "$limit": 20 } 28 ], 29 } 30 } 31 } 32 }, 33 { $limit: 20 } 34 ] )
Esta operación realiza las siguientes acciones:
Ejecuta las canalizaciones
inputCombina los resultados devueltos
Genera los primeros 20 documentos que son los resultados mejor clasificados 20 del pipeline
$rankFusion
Los ejemplos de Node.js en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte Primeros pasos en la documentación del controlador de MongoDB Node.js.
Para utilizar el controlador de MongoDB Node.js para agregar una etapa de $rankFusion a una canalización de agregación, utilice el Operador $rankFusion en un objeto de canalización.
Antes de ejecutar el siguiente ejemplo, debe crear un índice de búsqueda de Atlas llamado default. Incluya el siguiente código en su aplicación para crear un índice de búsqueda en la colección movies:
const index = { name: "default", definition: { mappings: { dynamic: true } } } const result = collection.createSearchIndex(index);
El siguiente ejemplo crea una etapa en la canalización que ejecuta dos pipelines, searchPlot y searchGenre, que realizan operaciones de $search usando el índice de búsqueda default. La etapa $rankFusion clasifica luego los resultados de búsqueda en base al peso asignado a cada pipeline $search y devuelve los resultados ordenados. La etapa $addFields incluye el campo scoreDetails en los documentos devueltos. El ejemplo luego ejecuta la canalización de agregación:
const pipeline = [ { $rankFusion: { input: { pipelines: { searchPlot: [ { $search: { index: "default", text: { query: "space", path: "plot"} } } ], searchGenre: [ { $search: { index: "default", text: { query: "adventure", path: "genres" } } } ] } }, combination: { weights: {searchPlot: 0.6, searchGenre: 0.4} }, scoreDetails: true } }, { $addFields: { scoreDetails: { $meta: "searchScoreDetails" } } } ]; const cursor = collection.aggregate(pipeline); return cursor;