Esta página descreve como classificar os resultados da pesquisa para pesquisas de texto completo no Spanner.
O Spanner suporta o cálculo de uma pontuação de topicalidade, que fornece um bloco de construção para criar funções de classificação sofisticadas. Estas classificações calculam a relevância de um resultado para uma consulta, com base na frequência do termo de consulta e noutras opções personalizáveis.
O exemplo seguinte mostra como fazer uma pesquisa classificada usando a função
SCORE
:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY SCORE(AlbumTitle_Tokens, "fifth symphony") DESC
PostgreSQL
Este exemplo usa spanner.search
com
spanner.score
.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
ORDER BY spanner.score(albumtitle_tokens, 'fifth symphony') DESC
Atribua uma pontuação aos termos de consulta com a função SCORE
A função SCORE
calcula uma pontuação para cada termo de consulta e, em seguida, combina as pontuações. A pontuação por termo baseia-se aproximadamente na frequência do termo – frequência inversa do documento
(TF/IDF). A pontuação é um
componente da ordenação final de um registo. A consulta combina-o com outros sinais, como a atualidade que modula a pontuação de relevância.
Na implementação atual, a parte IDF de TF/IDF só está disponível quando o enhance_query=>true
é usado. Calcula a frequência relativa das palavras com base no corpus Web completo usado pela Pesquisa Google, em vez de um índice de pesquisa específico. Se a melhoria da rquery não estiver ativada, a pontuação usa apenas o componente de frequência do termo (TF), ou seja, o termo IDF é definido como 1.
A função SCORE
devolve valores que servem como classificações de relevância que o Spanner usa para estabelecer uma ordem de ordenação. Não têm significado
autónomo. Quanto mais elevada for a pontuação, melhor corresponde à consulta.
Normalmente, os argumentos como query
e enhance_query
são os mesmos nas funções SEARCH
e SCORE
para garantir a consistência na obtenção e na classificação.
A forma recomendada de o fazer é usar estes argumentos com
parâmetros de consulta
em vez de literais de string e especificar os mesmos parâmetros de consulta nas funções
SEARCH
e SCORE
.
Pontue várias colunas
O Spanner usa a função SCORE
para classificar cada campo individualmente. Em seguida, a consulta combina estas pontuações individuais. Uma forma comum de o fazer é somar as classificações individuais e, em seguida, aumentá-las de acordo com as ponderações dos campos fornecidas pelo utilizador (que são fornecidas através de parâmetros de consulta SQL).
Por exemplo, a seguinte consulta combina a saída de duas funções 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
Este exemplo usa os parâmetros de consulta $1
e $2
, que estão associados a "quinta sinfonia" e "blue note", respetivamente.
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
O exemplo seguinte adiciona dois parâmetros de aumento:
- A atualização (
FreshnessBoost
) aumenta a pontuação com(1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30)
- A popularidade(
PopularityBoost
) aumenta a pontuação multiplicando-a pelo fator(1 + IF(HasGrammy, @grammyweight, 0)
.
Para facilitar a leitura, a consulta usa o 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
Este exemplo usa os parâmetros de consulta $1
, $2
, $3
, $4
, $5
e $6
que estão associados aos valores especificados para titlequery
, studioquery
,
titleweight
, studioweight
, grammyweight
e freshnessweight
,
respetivamente.
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
também pode ser usado na pesquisa e na pontuação para simplificar as consultas quando
adequado.
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
Este exemplo usa
spanner.tokenlist_concat
.
O parâmetro de consulta $1
está associado 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
Aumente as correspondências de pedidos de consultas
O Spanner aplica um aumento multiplicativo ao resultado da função SCORE
para valores que contêm os termos de consulta na mesma ordem em que aparecem na consulta. Existem duas versões deste aumento: correspondência parcial e correspondência exata. É aplicado um aumento de correspondência parcial quando:
- O
TOKENLIST
contém todos os termos originais na consulta. - Os tokens estão adjacentes entre si e na mesma ordem em que aparecem na consulta.
Existem algumas regras especiais para conjunções, negações e expressões:
- Uma consulta com uma negação não pode receber um aumento de correspondência parcial.
- Uma consulta com uma conjunção recebe um impulso se parte da conjunção aparecer nas localizações adequadas.
- Uma consulta com uma expressão recebe um impulso se a expressão aparecer no
TOKENLIST
, e o termo à esquerda da expressão na consulta aparecer à esquerda da expressão noTOKENLIST
, e o mesmo se aplica ao termo à direita da expressão.
O Spanner aplica um aumento de correspondência exata quando todas as regras anteriores são verdadeiras e os tokens primeiro e último na consulta são os tokens primeiro e último no documento.
Exemplo de documento: Bridge Over Troubled Water
Consulta | Otimização aplicada |
---|---|
Bridge Troubled | sem aumento |
Ponte sobre - outra água | sem aumento |
Bridge (Over OR Troubled) Water | sem aumento |
Passar por cima | reforço parcial |
Bridge Over (Troubled OR Water) | reforço parcial |
Bridge Over Troubled Water | aumento exato |
Ponte "Over Troubled" Water | aumento exato |
Bridge ("Over Troubled" OR missingterm) Water | aumento exato |
Limite a profundidade de obtenção
Os índices de pesquisa contêm frequentemente milhões de documentos. Para consultas em que os predicados têm baixa seletividade, não é prático classificar todos os resultados. As consultas de classificação têm normalmente dois limites:
- Limite de profundidade de obtenção: o número máximo de linhas a classificar.
- Limite do tamanho do conjunto de resultados: o número máximo de linhas que a consulta deve devolver (normalmente, o tamanho da página).
As consultas podem limitar a profundidade de obtenção com subconsultas 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
Este exemplo usa os parâmetros de consulta $1
, $2
e $3
, que estão associados aos valores especificados para title_query
, retrieval_limit
e page_size
, respetivamente.
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
Isto funciona particularmente bem se o Spanner usar o sinal de classificação mais importante para ordenar o índice.
O que se segue?
- Saiba mais sobre as consultas de pesquisa de texto integral.
- Saiba como fazer uma pesquisa de substring.
- Saiba como paginar os resultados da pesquisa.
- Saiba como misturar consultas de texto completo e sem texto.
- Saiba como pesquisar várias colunas.