Classificar os resultados da pesquisa

Esta página descreve como classificar os resultados da pesquisa de texto completo no Spanner.

O Spanner dá suporte ao cálculo da pontuação de utilidade, o que fornece uma elemento básico para criar funções de classificação sofisticadas. Essas pontuações calcular a relevância de um resultado para uma consulta com base no termo da consulta; e outras opções personalizáveis.

O exemplo a seguir mostra uma pesquisa classificada:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY SCORE(AlbumTitle_Tokens, "fifth symphony") DESC

Pontuar os termos de consulta com a função SCORE

A função SCORE calcula uma pontuação para cada termo de consulta e as combina. A pontuação por período é baseada, aproximadamente, na frequência do termo – documento inverso padrão (TF/IDF) (em inglês). A pontuação é um componente da ordenação final de um registro. A consulta o combina e outros sinais, como a atualização que modula a pontuação de utilidade.

Na implementação atual, a parte do IDF do TF/IDF só está disponível quando enhance_query=>true é usado. Ele calcula a frequência relativa das palavras com base no corpus da Web completo usado pela Pesquisa Google, em vez de um índice de pesquisa específico. Se o aprimoramento do rquery não estiver ativado, apenas a pontuação usa o termo componente de frequência (TF) (ou seja, o termo IDF é definido como 1).

A função SCORE retorna valores que servem como pontuações de relevância que o Spanner usa para estabelecer uma ordem de classificação. Eles não têm instâncias significado. Quanto maior a pontuação, melhor a correspondência com a consulta.

Normalmente, argumentos como query e enhance_query são os mesmos em ambos. SEARCH e SCORE para garantir consistência na recuperação e na classificação.

A maneira recomendada de fazer isso é usar esses 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.

Pontuar várias colunas

O Spanner usa o SCORE para pontuar cada campo individualmente. Em seguida, a consulta combina essas pontuações individuais juntas. Uma maneira comum de fazer isso é somar as pontuações individuais e, em seguida, aumentar de acordo com os pesos de campo fornecidos pelo usuário (que são fornecidos usando parâmetros de consulta SQL).

Por exemplo, a consulta a seguir combina a saída de duas funções SCORE:

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

O exemplo a seguir adiciona dois parâmetros de otimização:

  • 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 por fator (1 + IF(HasGrammy, @grammyweight, 0).

Para facilitar a leitura, a consulta usa o operador WITH.

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

TOKENLIST_CONCAT também pode ser usado na pesquisa e na pontuação para simplificar as consultas quando apropriado:

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

Otimizar correspondências de ordenação de consultas

É possível aplicar um aumento multiplicativo à pontuação de atualidade para valores que contêm os termos da consulta na mesma ordem em que aparecem na consulta. há duas versões dessa otimização: correspondência parcial e correspondência exata. Um aumento de correspondência parcial é aplicado quando:

  1. O TOKENLIST contém todos os termos originais da consulta.
  2. Os tokens são adjacentes e na mesma ordem em que aparecem na consulta.

Existem certas regras especiais para conjunções, negações e frases:

  • 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 for parte da conjunção aparecem nos locais apropriados.
  • Uma consulta com uma frase recebe um aumento se a frase aparecer no TOKENLIST e o termo à esquerda da frase na consulta aparecer à esquerda da frase no TOKENLIST. O mesmo se aplica ao termo à direita da frase.

O Spanner aplica um aumento de correspondência exata quando todos os regras forem verdadeiras. Os primeiros e últimos tokens na consulta são os primeiros e os últimos tokens no documento.

Exemplo de documento: Ponte sobre água instável

Consulta Otimização aplicada
Problemas na ponte sem aumento
Ponte sobre outra água sem aumento
Ponte (sobre ou com problemas) de água sem aumento
Ponte sobre aumento parcial
Ponte sobre (com problemas OU água) aumento parcial
Ponte sobre águas turbulentas aumento exato
Ponte "Over Troubled" Water aumento exato
Ponte ("Over Troubled" OR missingterm) Água otimização exata

Limitar a profundidade de recuperação

Os índices de pesquisa geralmente contêm milhões de documentos. Para consultas em que o predicados têm baixa seletividade, é impraticável classificar todos os resultados. As consultas de pontuação geralmente têm dois limites:

  1. Limite de profundidade de recuperação: o número máximo de linhas a serem pontuadas.
  2. Limite de tamanho do conjunto de resultados: o número máximo de linhas que a consulta deve ter. retornar (normalmente, o tamanho da página).

As consultas podem limitar a profundidade de recuperação com subconsultas SQL:

SELECT *
FROM (
  SELECT AlbumId
  FROM Albums
  WHERE SEARCH(Title_Tokens, @p1)
  ORDER BY ReleaseTimestamp DESC
  LIMIT @retrieval_limit
)
ORDER BY SCORE(Title_Tokens, @p1)
LIMIT @page_size

Isso funciona bem se o Spanner usar os dados mais importantes de classificação para ordenar o índice.

A seguir