En esta página, se describe cómo clasificar los resultados de la búsqueda de texto completo en Spanner.
Spanner admite el cálculo de una puntuación de relevancia del tema, que proporciona un componente básico para crear funciones de clasificación sofisticadas. Estas puntuaciones calculan la relevancia de un resultado para una búsqueda, según la frecuencia del término de búsqueda 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
Puntú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 la búsqueda y, luego, combina las puntuaciones. La puntuación por término se basa aproximadamente en la frecuencia de término-frecuencia de documento inversa (TF/IDF). La puntuación es un componente del ordenamiento final de un registro. La búsqueda la combina con otros indicadores, como la actualización que modula la puntuación de relevancia del tema.
En la implementación actual, la parte del 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 utiliza la Búsqueda de Google, en lugar de un índice de búsqueda específico. Si la mejora de rquery no está habilitada, la puntuación solo usa el componente de frecuencia del término (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 búsqueda.
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.
Cómo asignar una puntuación a varias columnas
Spanner usa la función SCORE para calificar cada campo de forma individual. Luego, la búsqueda 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 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) AND 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 "blue note", respectivamente.
SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, $1) AND 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 refuerzo:
- La actualidad (
FreshnessBoost) aumenta la puntuación en(1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30). - Popularidad(
PopularityBoost) aumenta la puntuación multiplicándola por el factor(1 + IF(HasGrammy, @grammyweight, 0).
Para facilitar la lectura, la consulta usa el operador WITH.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) AND 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) AND 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 búsqueda $1 está vinculado a "nota azul".
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
Aumenta la coincidencia del orden de la búsqueda
Spanner aplica un aumento multiplicativo al resultado de la función SCORE para los valores que contienen los términos de la búsqueda en el mismo orden en que aparecen en la búsqueda. Existen dos versiones de este aumento: concordancia parcial y concordancia exacta. Se aplica un aumento de la coincidencia parcial en los siguientes casos:
TOKENLISTcontiene todos los términos originales de la búsqueda.- Los tokens son adyacentes entre sí y están en el mismo orden en que aparecen en la búsqueda.
Existen ciertas reglas especiales para las conjunciones, las negaciones y las frases:
- Una búsqueda con una negación no puede recibir un aumento de la coincidencia parcial.
- Una búsqueda con una conjunción recibe un aumento si parte de la conjunción aparece en las ubicaciones adecuadas.
- Una búsqueda con una frase recibe una mejora si la frase aparece en el
TOKENLIST, y el término a la izquierda de la frase en la búsqueda 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 la concordancia exacta cuando se cumplen todas las reglas anteriores y el primer y el último token de la búsqueda son el primer y el último token del documento.
Documento de ejemplo: Puente sobre aguas turbulentas
| Consulta | Se aplicó el aumento |
|---|---|
| Bridge Troubled | Sin amplificación |
| Puente sobre otra agua | Sin amplificación |
| Agua de puente (sobre o bajo el agua) | Sin amplificación |
| Puente sobre | Aumento parcial |
| Bridge Over (Troubled OR Water) | Aumento parcial |
| Bridge Over Troubled Water | Amplificación exacta |
| Puente "Sobre aguas turbulentas" | Amplificación exacta |
| Puente ("Sobre aguas turbulentas" O término faltante) | Amplificación exacta |
Limita la profundidad de recuperación
Los índices de búsqueda suelen contener millones de documentos. En el caso de las búsquedas en las que los predicados tienen una baja selectividad, no es práctico clasificar todos los resultados. Por lo general, las consultas de puntuación tienen dos límites:
- Límite de profundidad de recuperación: Es la cantidad máxima de filas que se pueden calificar.
- 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 en SQL:
GoogleSQL
SELECT *
FROM (
SELECT AlbumId, Title_Tokens
FROM Albums
WHERE SEARCH(Title_Tokens, @p1)
ORDER BY ReleaseTimestamp DESC
LIMIT @retrieval_limit
)
ORDER BY SCORE(Title_Tokens, @p1)
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 *
FROM (
SELECT albumid, title_tokens
FROM albums
WHERE spanner.search(title_tokens, $1)
ORDER BY releasetimestamp DESC
LIMIT $2
) AS subquery
ORDER BY spanner.score(subquery.title_tokens, $1)
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 de texto completo.
- Obtén más 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 combinar búsquedas de texto completo y búsquedas que no son de texto.
- Obtén más información para buscar en varias columnas.