Descripción general
La búsqueda híbrida en Fess combina la búsqueda tradicional por palabras clave (BM25) con la búsqueda semántica (vectorial) y fusiona ambos conjuntos de resultados mediante Rank Fusion para producir clasificaciones más precisas y relevantes. Rank Fusion integra los resultados de múltiples buscadores en un único ranking optimizado.
En Fess 15.9, la búsqueda semántica (chunking de contenido + búsqueda vectorial) se proporciona como una función del núcleo. Una vez que la habilita, el buscador semántico se registra automáticamente con Rank Fusion. Consulte Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial) para su configuración.
La función de Rank Fusion de Fess integra múltiples resultados de búsqueda para proporcionar resultados de búsqueda más precisos.
Qué es Rank Fusion
Rank Fusion es una técnica que combina resultados de múltiples algoritmos de búsqueda o métodos de puntuación (por ejemplo, palabras clave/BM25 y búsqueda semántica/vectorial) para generar un único ranking optimizado.
Principales beneficios:
Combina las fortalezas de diferentes algoritmos
Mejora la precisión de búsqueda
Proporciona resultados de búsqueda diversos
Algoritmos compatibles
Fess soporta el algoritmo RRF (Reciprocal Rank Fusion) para Rank Fusion.
RRF (Reciprocal Rank Fusion)
RRF calcula una puntuación sumando el recíproco de la posición de cada documento en cada resultado de búsqueda. Cuando un documento es recuperado por múltiples buscadores, sus puntuaciones se suman.
Fórmula:
k: Parámetro constante que controla la influencia del rango (valor predeterminado: 20)rank(d): Posición del documento d en cada resultado de búsqueda (base 0)Σ: Suma sobre todos los buscadores en los que aparece el documento d
Nota
Cuando la fusión la realiza Fess (el comportamiento predeterminado), el algoritmo es siempre RRF y no se admite la ponderación por buscador: la contribución de cada buscador se suma con el mismo peso, y rank.fusion.rank_constant es el único ajuste que permite modificar la tendencia del ranking. Cuando la fusión la realiza el motor de búsqueda, se dispone de otras técnicas de combinación y de pesos por buscador (consulte Rank Fusion en el motor de búsqueda).
Configuración
fess_config.properties
Configuración básica:
| Propiedad | Predeterminado | Descripción |
|---|---|---|
rank.fusion.window_size | 200 | Número máximo de resultados recuperados de cada buscador para la fusión. Debe ser >= paging.search.page.max.size × 2 (200 de forma predeterminada); si se establece un valor menor, se eleva automáticamente a este mínimo (se registra una advertencia WARN al iniciar). |
rank.fusion.rank_constant | 20 | La constante k en la fórmula RRF. Un valor mayor reduce la diferencia de puntuación entre los resultados con mayor y menor rango. |
rank.fusion.threads | -1 | Número de hilos del grupo de hilos fijo que ejecuta múltiples buscadores en paralelo. Si se especifica 0 o menos, se usa availableProcessors × 3 ÷ 2 + 1 automáticamente (al tratarse de aritmética entera, la parte decimal se trunca; por ejemplo: 4 núcleos → 7, 5 núcleos → 8). |
rank.fusion.score_field | rf_score | Nombre del campo del documento de resultados utilizado para almacenar la puntuación fusionada. |
Nota
Cuándo se aplican los cambios de configuración
Los cuatro ajustes anteriores requieren reiniciar Fess para que un cambio se aplique. Los valores leídos de fess_config.properties se almacenan en caché en la JVM, por lo que modificar el archivo mientras Fess está en ejecución no tiene ningún efecto.
A modo de referencia, rank.fusion.window_size se lee una sola vez al iniciar y rank.fusion.threads se lee en el momento en que se crea el grupo de hilos. El grupo de hilos se crea cuando se registra un buscador distinto de default (por ejemplo, el buscador semántico), de modo que si la búsqueda semántica está deshabilitada no se crea ningún grupo de hilos.
Propiedades del sistema JVM
Los buscadores a utilizar se especifican como una propiedad del sistema JVM. Añada lo siguiente a fess.in.sh:
En el caso de fess.in.bat, escriba lo siguiente:
Esta propiedad se comporta de la siguiente manera:
Se establece como opción JVM, no en
fess_config.properties. Especifique el nombre de la clave tal cual:rank.fusion.searchers. Las formas con los prefijos-Dfess.config.o-Dfess.system., habituales en otros ajustes (por ejemplo,-Dfess.config.rank.fusion.searchers), no se reconocen.En lugar de una opción JVM, también puede escribirlo en una sola línea, como
rank.fusion.searchers=default,semantic_chunk, en el campo «Propiedades del sistema» de «Sistema > General» de la pantalla de administración. Tenga en cuenta que el valor de ese campo solo se aplica cuando todavía no existe una propiedad del sistema con el mismo nombre. Por ello, si se ha indicado con-D, la opción JVM tiene prioridad, y para modificar un valor que ya se ha aplicado es necesario reiniciar Fess.defaultes el buscador que realiza la búsqueda estándar por palabras clave y siempre está disponible.El nombre de un buscador se deriva del nombre de su clase de implementación eliminando el sufijo
Searchery convirtiendo el resto a snake_case en minúsculas (SemanticChunkSearcher→semantic_chunk). El buscador semántico integrado en el núcleo (Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial)) se registra con el nombresemantic_chunk.Si esta propiedad no se especifica, se utilizan todos los buscadores registrados. Si ninguno de los nombres especificados coincide con un buscador registrado, solo se utiliza el buscador
default. Si utiliza el buscador semántico integrado en el núcleo (Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial)), normalmente no necesita establecer esta propiedad en absoluto.La fusión de resultados se realiza únicamente cuando hay dos o más buscadores disponibles. Cuando solo hay un buscador disponible, no se realiza la fusión y se devuelven los resultados de búsqueda normales.
Advertencia
Si anteriormente utilizaba el plugin fess-webapp-semantic-search de Fess 15.7 o anterior, es posible que se le haya indicado que estableciera esta propiedad como -Drank.fusion.searchers=default,semantic. Ese plugin registraba su buscador con el nombre semantic, que es un buscador diferente del nombre del buscador integrado en el núcleo, semantic_chunk, introducido en la 15.9. Si traslada esa configuración de la era 15.7 a la 15.9 sin cambios, la lista de permitidos nunca incluye semantic_chunk, por lo que la búsqueda semántica integrada en el núcleo (chunking de contenido + búsqueda vectorial) no funciona en absoluto — Fess sigue devolviendo silenciosamente resultados de búsqueda por palabras clave normales (se registra una advertencia al iniciar, pero la exclusión por solicitud en sí solo se registra en el nivel DEBUG). Si su configuración especifica default,semantic, elimine este ajuste o añada semantic_chunk. Consulte «Migración desde la versión 15.7 o anterior» en Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial) para más detalles.
Rank Fusion en el motor de búsqueda
Si establece rank.fusion.engine.enabled=true, la fusión la realiza OpenSearch en lugar de Fess. Las consultas de los buscadores se combinan en una única solicitud de búsqueda (una consulta hybrid), y un search pipeline de OpenSearch normaliza y combina las puntuaciones. Como la fusión se realiza en una sola solicitud, el número total de resultados y los recuentos de las facetas también corresponden al conjunto de resultados fusionado.
Esto requiere el plugin neural-search de OpenSearch. Está incluido en la distribución estándar de OpenSearch y en la imagen ghcr.io/codelibs/fess-opensearch, pero no en la distribución mínima.
Los ajustes se escriben en fess_config.properties (un cambio requiere reiniciar Fess):
| Propiedad | Valor predeterminado | Descripción |
|---|---|---|
rank.fusion.engine.enabled | false | true hace que la fusión la realice el motor de búsqueda. |
rank.fusion.combination.technique | rrf | Cómo se combinan las puntuaciones: rrf, arithmetic_mean, geometric_mean o harmonic_mean. Con rrf, se utiliza rank.fusion.rank_constant como la constante k, lo que da la misma fórmula que cuando la fusión la realiza Fess. |
rank.fusion.normalization.technique | min_max | Cómo se normalizan las puntuaciones antes de combinarlas: min_max, l2 o z_score. No se utiliza con rrf. |
rank.fusion.combination.weights | (vacío) | Peso de cada buscador, como pares nombre:peso separados por comas (por ejemplo, default:0.7,semantic_chunk:0.3). Cada peso debe estar entre 0.0 y 1.0, los pesos deben sumar 1.0 y deben indicarse todos los buscadores que participan en la fusión. Si está vacío, los buscadores tienen el mismo peso. Un valor que no cumple estas reglas se notifica con un registro ERROR, y esa búsqueda la fusiona Fess. |
rank.fusion.pagination_depth | 1000 | Cuántos resultados aporta cada buscador a la fusión por shard. Limita la profundidad hasta la que un cliente puede paginar y el conjunto de documentos que se fusionan: una búsqueda fusionada en el motor de búsqueda puede paginar como máximo esta cantidad de resultados. El valor enviado al motor de búsqueda nunca supera indexer.max.result.window.size. |
Nota
La normalización z_score solo puede combinarse con arithmetic_mean. Se trata de una restricción del plugin neural-search. Si se combina con geometric_mean o harmonic_mean, Fess rechaza la combinación, escribe un registro ERROR que nombra ambas configuraciones y fusiona esa búsqueda por sí mismo.
En los siguientes casos el motor de búsqueda no realiza la fusión, y Fess fusiona los resultados en su lugar.
Una búsqueda que incluye parámetros de búsqueda avanzada (
as.*)Una búsqueda que especifica un criterio de ordenación, una búsqueda por geolocalización o una búsqueda de documentos similares. Estas omiten por completo la búsqueda semántica, por lo que los resultados provienen solo de la búsqueda por palabras clave (consulte Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial)).
Un valor de
rank.fusion.combination.weightsque no cumple las reglas anterioresLa normalización
z_scorecombinada congeometric_meanoharmonic_mean(un registro ERROR nombra ambas configuraciones)El motor de búsqueda no puede ejecutar solicitudes fusionadas en absoluto: no reconoce la consulta
hybrido el procesador del pipeline de búsqueda, por ejemplo porque falta el plugin neural-search o es demasiado antiguo. Se escribe un registro WARN en cada una de esas búsquedas, y la siguiente búsqueda vuelve a pedírselo al motor de búsqueda, de modo que la fusión en el motor se reanuda por sí sola, sin reiniciar Fess, en cuanto se instala o actualiza el plugin.
Cualquier otro fallo de una solicitud fusionada (una consulta no válida, un índice cerrado, un fallo de shard, etc.) se notifica solo para esa búsqueda, igual que sin la fusión en el motor de búsqueda, y la siguiente búsqueda vuelve a fusionarla el motor de búsqueda.
Tenga en cuenta lo siguiente cuando la fusión la realiza el motor de búsqueda.
rank.fusion.timeoutno se aplica. El embedding de la consulta se calcula de forma síncrona antes de enviar la solicitud de búsqueda, por lo que un proveedor de embeddings lento o que no responde retrasa la búsqueda hasta el tiempo de espera propio del proveedor (por ejemplo,content_chunker.embedding.ollama.timeout). Si el proveedor reintenta, los reintentos se suman a ese tiempo. Por ejemplo, el proveedor integradoopensearchrepite una espera decontent_chunker.embedding.opensearch.timeout(60000ms de forma predeterminada) hastacontent_chunker.embedding.opensearch.retry.max(3de forma predeterminada) veces, por lo que un proveedor que no responde puede retrasar una búsqueda 180 segundos de forma predeterminada, más las esperas entre reintentos.rank.fusion.window_sizeyrank.fusion.threadssolo se utilizan cuando la fusión la realiza Fess.Una búsqueda fusionada puede paginar como máximo
rank.fusion.pagination_depthresultados, porque el motor de búsqueda solo fusiona los primerosrank.fusion.pagination_depthresultados de cada buscador por shard. El número de páginas, el enlace a la página siguiente y los números de página se detienen ahí, y una página cuya posición inicial (start) esrank.fusion.pagination_deptho mayor se rechaza con el mismo error que, en cualquier otra búsqueda, una página más allá deindex.max_result_window(en la API de búsqueda v2, HTTP 400 coninvalid_request). Una página que empieza después del último resultado fusionado pero dentro de ese límite (por ejemplo, desde un enlace obsoleto) se devuelve vacía. Las búsquedas que no se fusionan en el motor de búsqueda pueden paginar hastaindex.max_result_window, como antes.El número total de resultados es exacto mientras sea inferior a
rank.fusion.pagination_depth. A partir de ese valor, el motor de búsqueda puede contar menos resultados de los que realmente coinciden, por lo que el número se informa como un límite inferior (en la API de búsqueda,record_count_relationesGREATER_THAN_OR_EQUAL_TO).Aumentar
rank.fusion.pagination_depthpermite paginar más a fondo, pero cada búsqueda fusionada recopila esa cantidad de resultados por buscador y shard, por lo que todas las búsquedas se vuelven más lentas, no solo las páginas profundas.El
kde la consulta knn del buscador semántico (el número de vecinos por shard) escontent_chunker.search.knn.k. Una búsqueda vectorial devuelve vecinos aunque su similitud sea baja, por lo que, sincontent_chunker.search.min_score, el número total de resultados incluye esos resultados vectoriales y, en un índice pequeño, puede abarcar la mayoría de los documentos que el usuario puede ver. Establezcacontent_chunker.search.min_scorepara acotarlo (consulte Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial)).El campo
searcherse añade a los resultados como de costumbre, perorf_scoreno.
Integración con la búsqueda híbrida
Rank Fusion es particularmente eficaz para la búsqueda híbrida, que combina la búsqueda por palabras clave y la búsqueda semántica. Para usar la búsqueda semántica, configure la función de chunking de contenido y establezca content_chunker.search.enabled=true.
Advertencia
Los ajustes content_chunker.*, como content_chunker.enabled y content_chunker.search.enabled, no pertenecen a fess_config.properties, sino que son propiedades del sistema. Escríbalos en conf/system.properties o especifíquelos como opción JVM, por ejemplo -Dfess.system.content_chunker.search.enabled=true. Si los escribe en fess_config.properties, no tendrán ningún efecto. Además, content_chunker.search.enabled solo se evalúa al iniciar, por lo que tras habilitarlo es necesario reiniciar Fess.
Consulte Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial) para más detalles.
Verificación de los resultados de la fusión
Puede comprobar si Rank Fusion está funcionando realmente mediante los dos campos siguientes, que se añaden a los resultados de búsqueda.
| Campo | Contenido |
|---|---|
searcher | Array con los nombres de los buscadores que recuperaron el documento (por ejemplo, ["default", "semantic_chunk"]). Si contiene ambos, significa que el documento coincidió tanto en la búsqueda por palabras clave como en la búsqueda semántica. |
rf_score | Puntuación fusionada calculada mediante RRF. El nombre del campo se puede cambiar con rank.fusion.score_field. |
Ambos son valores que se añaden dinámicamente en el momento de la búsqueda y no se almacenan en el índice. Además, de forma predeterminada no se incluyen en la respuesta de /api/v2/search, por lo que, para consultarlos, establezca lo siguiente en fess_config.properties y reinicie Fess:
Nota
query.additional.api.response.fields es un ajuste que añade elementos a la lista de permitidos de los campos que pueden incluirse en la respuesta de la API de búsqueda v2. No añada campos de control de acceso como role o virtual_host, ya que la información de control de acceso quedaría expuesta en la respuesta de la API de búsqueda.
Impacto en el número de resultados
Cuando Rank Fusion lo realiza Fess, el número total de resultados devuelto no es sin más el del buscador principal (el buscador default registrado en primer lugar), sino que se corrige de la siguiente manera:
El valor de corrección es el número de documentos que, estando entre los window_size ÷ 2 primeros resultados tras la fusión, no estaban entre los window_size ÷ 2 primeros resultados del buscador principal. Es decir, el número aumenta en la cantidad de documentos que solo encontró la búsqueda semántica. Por ello, para una misma consulta el número de resultados puede variar según si la búsqueda híbrida está habilitada o no.
Tenga en cuenta que, si el número total de resultados del buscador principal se devuelve como un valor aproximado (un límite inferior), esta corrección no se aplica. Los recuentos de facetas (etiquetas, etc.) también se toman tal cual de los resultados del buscador principal.
Cuando la fusión la realiza el motor de búsqueda (consulte Rank Fusion en el motor de búsqueda), el número total de resultados y los recuentos de facetas abarcan la unión de los resultados de la búsqueda por palabras clave y de la búsqueda semántica. Cada buscador aporta como máximo rank.fusion.pagination_depth resultados por shard, y el buscador semántico está limitado además por content_chunker.search.knn.k. Por ello, una misma consulta informa un número total de resultados y unos recuentos de facetas distintos según rank.fusion.engine.enabled, y en un índice pequeño suelen ser mayores cuando la fusión la realiza el motor de búsqueda, porque la búsqueda semántica aporta sus resultados.
Ejemplos de uso
Búsqueda híbrida básica
Calcular la puntuación BM25 con la búsqueda por palabras clave
Calcular la similitud vectorial con la búsqueda semántica
Fusionar ambos resultados con RRF
Generar el ranking final
Flujo de búsqueda:
Consideraciones de rendimiento
Uso de memoria
El uso de memoria aumenta porque se retienen múltiples resultados de búsqueda.
Use
rank.fusion.window_sizepara limitar el número máximo de resultados a fusionar. El buscador principal (el buscadordefaulten primer lugar) recupera hastawindow_sizeresultados, mientras que cada uno de los demás buscadores recuperawindow_size ÷ número de buscadoresresultados (número de buscadoreses el total incluyendo el buscador principal, y la división se trunca).Por ejemplo, con dos buscadores (
defaultysemantic_chunk) ywindow_size=200, el buscador principal recupera 200 resultados y el buscador semántico 100, por lo que se retienen como máximo 300 documentos.
Advertencia
rank.fusion.window_size no puede ser inferior a paging.search.page.max.size × 2. Si paging.search.page.max.size tiene su valor predeterminado 100, el límite inferior es 200, que coincide con el valor predeterminado de rank.fusion.window_size. Es decir, en la configuración predeterminada no es posible establecer window_size por debajo de su valor predeterminado. Si establece un valor menor, se registra una advertencia WARN al iniciar y el valor se eleva a 200. Para reducirlo realmente es necesario reducir antes paging.search.page.max.size, pero esto también reduce el número máximo de resultados que se pueden solicitar por página desde la pantalla de búsqueda y la API.
Tiempo de procesamiento
El tiempo de respuesta aumenta porque se ejecutan múltiples búsquedas.
Use
rank.fusion.threadspara establecer el número de hilos para la ejecución paralela.
Nota
Cuando la fusión la realiza Fess, se espera a los buscadores distintos del principal un máximo de rank.fusion.timeout milisegundos (predeterminado 10000). Un buscador que no ha respondido en ese plazo queda excluido de esa búsqueda, y los resultados se marcan como parciales (tiempo de espera agotado). Al buscador principal siempre se le espera. Con 0 o menos, se espera sin límite. Este ajuste no se aplica cuando la fusión la realiza el motor de búsqueda (consulte Rank Fusion en el motor de búsqueda).
Comportamiento cuando falla un buscador
Si alguno de los buscadores falla con una excepción, sus resultados se tratan como vacíos: se registra una advertencia WARN y la fusión continúa únicamente con los resultados de los buscadores restantes. La propia solicitud de búsqueda no produce ningún error.
Sin embargo, los errores de sintaxis de consulta (InvalidQueryException) y la superación del límite de paginación (ResultOffsetExceededException) son excepciones a esta regla: estos se devuelven como errores tal cual. Además, en las páginas profundas en las que no se realiza la fusión (donde posición de inicio × 2 es mayor o igual que rank.fusion.window_size), una excepción producida en el buscador principal se devuelve tal cual como error de la solicitud de búsqueda.
El buscador semántico devuelve resultados vacíos cuando no puede conectarse al proveedor de embeddings o cuando falla el procesamiento de los embeddings. También en este caso no se produce ningún error, y solo se obtienen los resultados de la búsqueda por palabras clave.
Solución de problemas
Los resultados de búsqueda difieren de lo esperado
Síntoma: Los resultados tras Rank Fusion difieren de lo esperado
Verificaciones:
Verificar el campo
searcher(consulte «Verificación de los resultados de la fusión»). Si todos los documentos muestran únicamente["default"], el buscador semántico no está devolviendo resultados.Comprobar si la búsqueda semántica se está omitiendo. En las consultas que contienen sintaxis de búsqueda como frases o comodines, así como en las búsquedas con ordenación, la búsqueda por ubicación y la búsqueda de documentos similares, el buscador semántico no devuelve resultados y solo se obtienen los de la búsqueda por palabras clave. Consulte Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial) para más detalles sobre las condiciones de omisión.
Verificar los resultados de cada tipo de búsqueda individualmente
Ajustar el valor de
rank.fusion.rank_constantEn páginas profundas (donde
posición de inicio × 2es mayor o igual querank.fusion.window_size; de forma predeterminada, a partir del resultado 101), la fusión no se realiza y solo se utiliza el buscador principal. Si desea resultados fusionados en más páginas, aumenterank.fusion.window_size. Cuando la fusión la realiza el motor de búsqueda, este límite no existe: se fusionan todas las páginas, hastarank.fusion.pagination_depthresultados (consulte Rank Fusion en el motor de búsqueda).
La búsqueda es lenta
Síntoma: La búsqueda se vuelve lenta cuando Rank Fusion está habilitado
Soluciones:
Ajustar
rank.fusion.threads:Reducir
rank.fusion.window_size. Sin embargo, no puede quedar por debajo de su límite inferior (paging.search.page.max.size × 2), por lo que en la configuración predeterminada se deben establecer los dos ajustes siguientes conjuntamente:Tenga en cuenta que el número máximo de resultados que se pueden solicitar por página también se reduce. Tras aplicar la configuración es necesario reiniciar.
Cuando la fusión la realiza el motor de búsqueda, reducir
rank.fusion.pagination_depth. Esto también reduce la profundidad hasta la que se pueden paginar los resultados fusionados. Tras cambiarlo es necesario reiniciar.
Memoria insuficiente
Síntoma: Se produce OutOfMemoryError
Soluciones:
Reducir
rank.fusion.window_sizesiguiendo el mismo procedimiento que en «La búsqueda es lenta»Aumentar el tamaño del heap de JVM
Referencia
Búsqueda Semántica (Chunking de Contenido + Búsqueda Vectorial) - Configuración de la búsqueda semántica (chunking de contenido)
Descripción general del scripting - Descripción general de scripting
Configuración de Búsqueda Avanzada - Configuración avanzada de búsqueda
Descripción general de la búsqueda IA (RAG) y la integración LLM - Guía de integración LLM (Búsqueda semántica)