En esta página, se describe cómo clasificar los resultados de la búsqueda para las búsquedas en el texto completo en Spanner.
Spanner admite el cálculo de una puntuación de actualidad, que proporciona un componente básico para crear funciones de clasificación sofisticadas. Estas puntuaciones calculan la relevancia de un resultado para una consulta, según la frecuencia del término de la consulta y otras opciones personalizables.
En el siguiente ejemplo, se muestra cómo realizar una búsqueda clasificada con la función
SCORE:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY SCORE(AlbumTitle_Tokens, "fifth symphony") DESC
PostgreSQL
En este ejemplo, se usa spanner.search
con
spanner.score.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
ORDER BY spanner.score(albumtitle_tokens, 'fifth symphony') DESC
Asigna una puntuación a los términos de búsqueda con la función SCORE
La función SCORE
calcula una puntuación para cada término de búsqueda y, luego, combina las puntuaciones. La
puntuación por término se basa, aproximadamente, en la frecuencia de término-frecuencia inversa de documento
(TF/IDF). La puntuación es un
componente del ordenamiento final de un registro. La consulta la combina con otros indicadores, como la actualidad, que modula la puntuación de actualidad.
En la implementación actual, la parte de IDF de TF/IDF solo está disponible cuando
se usa enhance_query=>true. Calcula la frecuencia relativa de las palabras
en función del corpus web completo que usa la Búsqueda de Google, en lugar de un
índice de búsqueda específico. Si no se habilita la mejora de rquery, la puntuación solo
usa el componente de frecuencia de términos (TF) (es decir, el término IDF se establece en 1).
La función SCORE devuelve valores que sirven como puntuaciones de relevancia que Spanner usa para establecer un orden de clasificación. No tienen un significado independiente. Cuanto más alta sea la puntuación, mejor coincidirá con la consulta.
Por lo general, los argumentos como query y enhance_query son los mismos en las funciones SEARCH y SCORE para garantizar la coherencia en la recuperación y la clasificación.
La forma recomendada de hacerlo es usar estos argumentos con
parámetros de consulta,
en lugar de literales de cadena, y especificar los mismos parámetros de consulta en las
funciones SEARCH y SCORE.
Asigna puntuaciones a varias columnas
Spanner usa la función SCORE para puntuar cada campo
de forma individual. Luego, la consulta combina estas puntuaciones individuales. Una forma común
de hacerlo es sumar las puntuaciones individuales y, luego, aumentarlas
según las ponderaciones de campo proporcionadas por el usuario (que se proporcionan con los parámetros de consulta en SQL).
Por ejemplo, la siguiente consulta combina el resultado de dos funciones SCORE:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR SEARCH(Studio_Tokens, @p2)
ORDER BY SCORE(Title_Tokens, @p1) * @titleweight + SCORE(Studio_Tokens, @p2) * @studioweight
LIMIT 25
PostgreSQL
En este ejemplo, se usan los parámetros de consulta $1 y $2, que están vinculados a
"quinta sinfonía" y "nota azul", respectivamente.
SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, $1) OR spanner.search(studio_tokens, $2)
ORDER BY spanner.score(title_tokens, $1) * $titleweight
+ spanner.score(studio_tokens, $2) * $studioweight
LIMIT 25
En el siguiente ejemplo, se agregan dos parámetros de potenciación:
- La actualidad (
FreshnessBoost) aumenta la puntuación con(1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30) - La popularidad(
PopularityBoost) aumenta la puntuación multiplicándola por el factor(1 + IF(HasGrammy, @grammyweight, 0).
Para mejorar la legibilidad, la consulta usa el operador WITH.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR SEARCH(Studio_Tokens, @p2)
ORDER BY WITH(
TitleScore AS SCORE(Title_Tokens, @p1) * @titleweight,
StudioScore AS SCORE(Studio_Tokens, @p2) * @studioweight,
DaysOld AS (UNIX_MICROS(CURRENT_TIMESTAMP()) - ReleaseTimestamp) / 8.64e+10,
FreshnessBoost AS (1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30),
PopularityBoost AS (1 + IF(HasGrammy, @grammyweight, 0)),
(TitleScore + StudioScore) * FreshnessBoost * PopularityBoost)
LIMIT 25
PostgreSQL
En este ejemplo, se usan los parámetros de consulta $1, $2, $3, $4, $5 y $6,
que están vinculados a los valores especificados para titlequery, studioquery,
titleweight, studioweight, grammyweight y freshnessweight,
respectivamente.
SELECT albumid
FROM
(
SELECT
albumid,
spanner.score(title_tokens, $1) * $3 AS titlescore,
spanner.score(studio_tokens, $2) * $4 AS studioscore,
(extract(epoch FROM current_timestamp) * 10e+6 - releasetimestamp) / 8.64e+10 AS daysold,
(1 + CASE WHEN hasgrammy THEN $5 ELSE 0 END) AS popularityboost
FROM albums
WHERE spanner.search(title_tokens, $1) OR spanner.search(studio_tokens, $2)
) AS subquery
ORDER BY (subquery.TitleScore + subquery.studioscore)
* (1 + $6 * greatest(0, 30 - subquery.daysold) / 30) * subquery.popularityboost
LIMIT 25
TOKENLIST_CONCAT
también se puede usar en la búsqueda y la puntuación para simplificar las consultas cuando
sea apropiado.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
ORDER BY SCORE(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
LIMIT 25
PostgreSQL
En este ejemplo, se usa
spanner.tokenlist_concat.
El parámetro de consulta $1 está vinculado a "blue note".
SELECT albumid
FROM albums
WHERE spanner.search(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
ORDER BY spanner.score(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
LIMIT 25
Aumentar las coincidencias de orden de búsqueda
Spanner aplica un aumento multiplicativo al resultado de la función SCORE para los valores que contienen los términos de búsqueda en el mismo orden en que aparecen en la consulta. Hay dos versiones de este aumento: coincidencia parcial
y coincidencia exacta. Se aplica un aumento de coincidencia parcial en los siguientes casos:
TOKENLISTcontiene todos los términos originales de la consulta.- Los tokens son adyacentes entre sí y están en el mismo orden en que aparecen en la consulta.
Existen ciertas reglas especiales para las conjunciones, las negaciones y las frases:
- Una consulta con una negación no puede recibir un aumento de coincidencia parcial.
- Una consulta con una conjunción recibe un aumento si parte de la conjunción aparece en las ubicaciones adecuadas.
- Una consulta con una frase recibe un aumento si la frase aparece en el
TOKENLIST, y el término a la izquierda de la frase en la consulta aparece a la izquierda de la frase en elTOKENLIST, y lo mismo se aplica al término a la derecha de la frase.
Spanner aplica un aumento de concordancia exacta cuando todas las reglas anteriores son verdaderas, y los primeros y últimos tokens de la consulta son los primeros y últimos tokens del documento.
Documento de ejemplo: Bridge Over Troubled Water
| Consulta | Se aplicó el potenciador |
|---|---|
| Bridge Troubled | sin boost |
| Puente sobre otro cuerpo de agua | sin boost |
| Bridge (Over OR Troubled) Water | sin boost |
| Bridge Over | potenciación parcial |
| Bridge Over (Troubled OR Water) | potenciación parcial |
| Bridge Over Troubled Water | impulso exacto |
| Bridge "Over Troubled" Water | impulso exacto |
| Bridge ("Over Troubled" OR missingterm) Water | impulso exacto |
Versiones de Scorer
El algoritmo de puntuación se actualiza periódicamente. Cada versión incluye un conjunto de mejoras en el algoritmo de puntuación. Para obtener una lista detallada de las diferencias entre las versiones, consulta Versiones del anotador.
Puedes establecer la versión predeterminada del puntuador para tu base de datos o especificar una versión para una consulta específica.
Si no especificas una versión del anotador para tu base de datos o consulta, la versión predeterminada del anotador se actualiza automáticamente cuando se lanza una versión posterior.
Establece la versión predeterminada del asignador de puntuación de la base de datos
Puedes establecer la versión predeterminada del algoritmo de puntuación para tu base de datos. Esta
opción determina qué versión del algoritmo de puntuación
usa Spanner cuando se llama a la función SCORE sin una
opción de puntuación version explícita.
GoogleSQL
Configura la opción de base de datos score_version:
ALTER DATABASE database_name SET OPTIONS (score_version = 2)
PostgreSQL
Configura la opción de base de datos spanner.score_version:
ALTER DATABASE database_name SET "spanner.score_version" = 2
Los valores válidos para la opción de base de datos son 1 o 2. Si el parámetro version
está presente en una solicitud, anula la versión predeterminada de la base de datos.
Anula la versión del anotador por consulta
Puedes anular la versión predeterminada del puntuador para una consulta específica con el
parámetro version en el argumento options de la función SCORE. Si una consulta
define una versión del puntuador, anula la versión predeterminada de la base de datos.
En el siguiente ejemplo, se anula la versión predeterminada del anotador especificando
version en el parámetro options:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, @query)
ORDER BY SCORE(
AlbumTitle_Tokens,
@query,
options=>JSON '{"version": 2}'
) DESC
PostgreSQL
En este ejemplo, se usa el parámetro de consulta $1, que está vinculado a la cadena de consulta.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, $1)
ORDER BY spanner.score(
albumtitle_tokens,
$1,
options => '{"version": 2}'::jsonb
) DESC
Limita la profundidad de la recuperación
Los índices de búsqueda suelen contener millones de documentos. En el caso de las consultas en las que los predicados tienen una selectividad baja, no es práctico clasificar todos los resultados. Las consultas de puntuación suelen tener dos límites:
- Límite de profundidad de recuperación: Es la cantidad máxima de filas que se puntuarán.
- Límite de tamaño del conjunto de resultados: Es la cantidad máxima de filas que debe devolver la consulta (por lo general, el tamaño de la página).
Las consultas pueden limitar la profundidad de recuperación con subconsultas de SQL:
GoogleSQL
SELECT AlbumId
FROM
(
SELECT AlbumId, SCORE(Title_Tokens, @p1) AS score
FROM Albums
WHERE SEARCH(Title_Tokens, @p1)
ORDER BY ReleaseTimestamp DESC
LIMIT @retrieval_limit
)
ORDER BY score DESC
LIMIT @page_size
PostgreSQL
En este ejemplo, se usan los parámetros de consulta $1, $2 y $3, que están vinculados a
los valores especificados para title_query, retrieval_limit y page_size,
respectivamente.
SELECT albumid
FROM
(
SELECT albumid, spanner.score(title_tokens, $1) AS score
FROM albums
WHERE spanner.search(title_tokens, $1)
ORDER BY releasetimestamp DESC
LIMIT $2
) AS subquery
ORDER BY score DESC
LIMIT $3
Esto funciona muy bien si Spanner usa el indicador de clasificación más importante para ordenar el índice.
¿Qué sigue?
- Obtén más información sobre las consultas de búsqueda en el texto completo.
- Obtén información para realizar una búsqueda de subcadena.
- Obtén más información para paginar los resultados de la búsqueda.
- Obtén más información para mezclar consultas de texto completo y que no sean de texto.
- Obtén más información para buscar en varias columnas.