Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

$rankFusion (agregación)

Importante

$rankFusion solo está disponible para implementaciones que utilizan MongoDB 8.0 o superior.

$rankFusion

$rankFusion Primero 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.

$rankFusion genera un conjunto clasificado de documentos en función de los rangos en que aparecen los documentos de entrada en sus pipelines de entrada y los pesos de los pipelines. Esta etapa utiliza el algoritmo de Fusión de Ranking Recíproco para clasificar los resultados combinados de los pipelines de entrada.

Utiliza $rankFusion para buscar documentos en una sola colección basándose en múltiples criterios y recuperar un conjunto de resultados finales clasificados que tiene en cuenta todos los criterios especificados.

La etapa tiene la siguiente sintaxis:

{ $rankFusion: {
input: {
pipelines: {
<myPipeline1>: <expression>,
<myPipeline2>: <expression>,
...
}
},
combination: {
weights: {
<myPipeline1>: <numeric expression>,
<myPipeline2>: <numeric expression>,
...
}
},
scoreDetails: <bool>
} }

$rankFusion requiere los siguientes campos:

Campo
Tipo
Descripción

input

Objeto

Define la entrada que clasifica $rankFusion.

input.
pipelines

Objeto

Contiene un mapa de nombres de pipelines a las etapas de agregación que definen ese pipeline. input.pipelines debe contener al menos una pipeline. Todas las pipelines deben funcionar en la misma colección y tener un nombre único.

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.

combination

Objeto

Opcional. Define cómo combinar los resultados del pipeline input.

combination.
weights

Objeto

opcional. Contiene un mapa desde input nombres de pipeline hasta sus pesos relativos a otras pipelines. Cada valor de peso debe ser un número no negativo (entero o decimal).

Si no especifica un peso, el valor predeterminado es 1.

scoreDetails

Booleano

El valor predeterminado es falso. Especifica si $rankFusion calcula y rellena el $scoreDetails campo de metadatos para cada documento de salida. Consulte la sección "scoreDetails" para obtener más información sobre este campo.

Solo puedes usar $rankFusion con una única colección. No puedes usar esta etapa de agregación en el ámbito de la base de datos.

$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.

Cada input pipeline debe ser tanto un pipeline de selección como un pipeline de clasificación.

Una pipeline 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 a través de diferentes pipelines de entrada, lo que requiere que todas las pipelines de entrada produzcan los mismos documentos sin modificar.

Nota

Si deseas modificar los documentos que buscas con $rankFusion, realiza esas modificaciones después de la etapa $rankFusion.

Una pipeline de selección debe contener únicamente las siguientes etapas:

Tipo
Etapas

Etapas de búsqueda

Si usas $geoNear en un pipeline de selección, no puedes especificar includeLogs o distanceField porque esos campos modifican los documentos.

Etapas de ordenamiento

Etapas de paginación

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:

Los nombres de las pipeline en input deben cumplir con 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 \0 en ninguna parte de la cadena

  • No debe contener una .

$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 ubicación de documentos en los resultados de la pipeline de entrada

  • La cantidad de veces que un documento aparece en diferentes canales de entrada

  • El weights de los pipelines de entrada.

Por ejemplo, si un documento tiene una alta clasificación en múltiples conjuntos de resultados de la pipeline, la puntuación RRF para ese documento sería más alta que si ese mismo documento tiene la misma clasificación en algunas pipelines de entrada, pero no está presente (o tiene una clasificación más baja) en las otras pipelines

La Fórmula de Fusión de Rango Recíproco (RRF) es equivalente a la siguiente operación algebraica:

La fórmula de fusión de rangos recíprocos
haga clic para ampliar

Nota

En esta fórmula, 60 es un parámetro de sensibilidad que MongoDB determinó.

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 que se está calculando la puntuación RRF.

R

El conjunto de rangos para las canalizaciones de entrada en las que aparece d.

r(d)

El rango del documento d en este pipeline de entrada.

w

El peso de la tubería de entrada en la que aparece d.

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.

Considera una etapa de la pipeline $rankFusion con una pipeline de entrada de $search y una de $vectorSearch.

Todas los pipelines de entrada producen los mismos 3 documentos: Document1, Document2 y Document3.

La $search pipeline clasifica los documentos en el siguiente orden:

  1. Document3

  2. Document2

  3. Document1

La $vectorSearch pipeline clasifica los documentos en el siguiente orden:

  1. Document1

  2. Document2

  3. Document3.

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.

Si estableces 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:

  • usa una etapa $project después de $rankFusion para proyectar el campo scoreDetails

  • usa una etapa $addFields después de $rankFusion para agregar el campo scoreDetails a la salida del pipeline

El campo scoreDetails contiene los siguientes subcampos:

Campo
Descripción

value

El valor numérico del PuntuaciónRRF para este documento.

description

Una descripción de cómo $rankFusion calculó el puntaje de RRF.

details

Un arreglo en el que cada entrada contiene información sobre las pipelines de entrada que generan este documento.

Cada entrada de arreglo en el campo details contiene los siguientes subcampos:

Campo
Descripción

inputPipelineName

El nombre de la pipeline de entrada que generó este documento.

rank

El rango de este documento en la pipeline de entrada. El rango es N/A en la salida de una etapa de la pipeline si un documento que se devuelve en la salida de otras etapas de la pipeline no está presente en la salida de esa etapa de la pipeline.

weight

El peso de la pipeline de entrada.

value

Opcional. Si la canalización de entrada genera un { $meta: 'score' } para este documento, value contiene { $meta: 'score' }.

description

opcional. Si la pipeline de entrada da salida a un campo description como parte de los scoreDetails para este documento, details.description contiene ese valor de campo.

details

El campo scoreDetails del pipeline de entrada. Si el pipeline de entrada no produce un campo scoreDetails, este campo es un arreglo vacío.

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 los pipelines 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: []
}
]
}

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.

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.

Índice de búsqueda
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 consultas de $vectorSearch query contra ese campo.

Índice vectorSearch
db.embedded_movies.createSearchIndex(
"vector_index",
"vectorSearch",
{
"fields": [
{
"type": "vector",
"path": "<FIELD_NAME>",
"numDimensions": <NUMBER_OF_DIMENSIONS>,
"similarity": "dotProduct"
}
]
}
);

El siguiente pipeline de agregación usa $rankFusion con los siguientes pipelines de entrada:

pipeline
Número de Documentos Devueltos
Descripción

searchOne

20

Ejecuta una búsqueda vectorial en el campo indexado como tipo vector para el término especificado como embeddings. La query considera hasta 500 vecinos más cercanos, pero limita los resultados a 20 documentos.

searchTwo

20

Ejecuta una búsqueda de texto completo para el mismo término y limita los resultados a 20 documentos.

1db.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 input pipelines

  • Combina los resultados devueltos

  • Muestra los primeros 20 documentos que son los primeros 20 resultados clasificados 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, debes crear un índice de búsqueda de Atlas llamado default. Incluye el siguiente código en tu 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;

Volver

Activar o desactivar la salida del registro

En esta página