Fazer recuperação top-k eficiente

Muitos aplicativos consultam um banco de dados para preencher uma única página no aplicativos conteinerizados. Nesses aplicativos, o aplicativo não precisa de todas as correspondências, mas apenas das principais correspondências com base na ordem de classificação do índice. Os índices de pesquisa podem implementar esse tipo de pesquisa de maneira muito eficiente. Esta página descreve como cria e pesquisa um índice que tenha correspondência top-k.

Criar índices de pesquisa para as correspondências top-k

Para configurar um índice de pesquisa para a correspondência top-k, use ORDER BY para ordenar o índice de pesquisa por uma coluna específica. As consultas precisam ter uma cláusula ORDER BY que corresponda exatamente à ordem de classificação do índice de pesquisa (incluindo ordem crescente e decrescente) e uma cláusula LIMIT que solicite que a consulta pare após encontrar k linhas correspondentes.

Também é possível implementar a paginação usando essas cláusulas. Para mais informações, consulte Paginar consultas de pesquisa.

Para alguns casos de uso, pode fazer sentido manter vários índices de pesquisa classificados por colunas diferentes. Marcar como "Gostei" particionamento, há uma troca entre custo de gravação e armazenamento e latência de consulta.

Por exemplo, considere uma tabela que usa o seguinte esquema:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  RecordTimestamp INT64 NOT NULL,
  ReleaseTimestamp INT64 NOT NULL,
  ListenTimestamp INT64 NOT NULL,
  AlbumTitle STRING(MAX),
  AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsRecordTimestampIndex
ON Albums(AlbumTitle_Tokens, SingerId_Tokens)
ORDER BY RecordTimestamp DESC
STORING ListenTimestamp

CREATE SEARCH INDEX AlbumsReleaseTimestampIndex
ON Albums(AlbumTitle_Tokens)
ORDER BY ReleaseTimestamp DESC
STORING ListenTimestamp

Consultar índices de pesquisa para as principais correspondências

Como mencionado anteriormente, as consultas precisam ter uma cláusula ORDER BY que corresponda exatamente à ordem de classificação do índice de pesquisa (incluindo ordem crescente e decrescente) e uma cláusula LIMIT que solicite que a consulta pare após encontrar k linhas correspondentes.

Confira a seguir algumas consultas comuns:

  • A consulta a seguir é muito eficiente. Ela seleciona Índice de AlbumsRecordTimestampIndex. Mesmo que haja muitos álbuns com a palavra "happy", a consulta só verifica um pequeno número de linhas:

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY RecordTimestamp DESC
    LIMIT 10
    
  • A mesma consulta, solicitando a ordem de classificação por ReleaseTimestamp em ordem decrescente usa o índice AlbumsReleaseTimestampIndex e é igualmente eficiente:

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY ReleaseTimestamp DESC
    LIMIT 10
    
  • Ao mesmo tempo, uma consulta que solicita a ordem de classificação por ListenTimestamp não executar uma consulta Top-K com eficiência. Ele precisa buscar todos os álbuns correspondentes, classificá-los por ListenTimestamp, e retornar os 10 primeiros. Essa consulta usa mais recursos se houver um grande número de documentos que contenham o termo "happy".

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY ListenTimestamp DESC
    LIMIT 10`
    
  • Da mesma forma, uma consulta não será executada de forma eficiente se solicitar que os resultados sejam em ordem crescente usando a coluna RecordTimestamp. Ele verifica todos linhas com a palavra "happy", mesmo com uma LIMIT.

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY RecordTimestamp ASC
    LIMIT 10
    

A seguir