Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
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 todos los pipelines de entrada de forma independiente y luego desduplica y combina los resultados de los pipelines de entrada en un conjunto final de resultados clasificados.

$rankFusion genera un conjunto de documentos clasificados en función de las posiciones en las que aparecen los documentos de entrada en sus respectivas canalizaciones de entrada y de los pesos de dichas canalizaciones. Esta etapa utiliza el Algoritmo de fusión de rango recíproco para clasificar los resultados combinados de las canalizaciones 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 señal 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 del pipeline de entrada, consulta Input pipeline y Nombres de Input pipeline.

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 se especifica un peso, el valor por defecto es 1.

scoreDetails

Booleano

El valor por defecto es falso. Especifica si $rankFusion calcula y rellena el campo de metadatos $scoreDetails para cada documento de salida. Consulta 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 elimina los duplicados en los resultados a través de múltiples pipelines de entrada en la salida final. Cada documento de entrada único aparece como máximo una vez en la salida $rankFusion, independientemente de la cantidad de veces que el documento aparezca en los resultados de la pipeline 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

Etapas de pedido

Etapas de paginación

Una pipeline clasificada clasifica u ordena documentos. $rankFusion utiliza el orden de los resultados clasificados de la pipeline para influir en la clasificación de la salida. Las pipeline 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 ningún lugar de la string.

  • No debe contener un .

$rankFusion ordena los resultados según la Fórmula de Fusión de Rango Recíproco (RRF). Esta etapa ubica el puntaje RRF para cada documento en el campo de metadatos score de los resultados de salida. La fórmula RRF clasifica los documentos combinando 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 pipelines

  • 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 por rango recíproco
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 para toda la operación.

d

El documento para el que se está calculando la puntuación RRF.

R

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

r(d)

El rango del documento d en este pipeline de entrada.

w

El peso del pipeline en el 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 el puntaje RRF para Document1 a través de 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 configuras 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ón RRF 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 pipeline 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. Crea índices de tipo search y vectorSearch en la colección.

La siguiente definición de índice indexa automáticamente todos los campos indexables dinámicos en la colección para ejecutar $search consultas contra los campos 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/desactivar salida de registro

En esta página