Visão geral da consulta

Esta página descreve a função SEARCH e o modo de consulta aprimorado, que são usados para executar consultas de pesquisa de texto completo em tabelas do Spanner.

Consultar um índice de pesquisa

O Spanner fornece a função SEARCH para usar em consultas de índice de pesquisa. Um exemplo de caso de uso seria um app em que os usuários inserem texto em uma caixa de pesquisa, e o app envia a entrada do usuário diretamente para a função SEARCH. A função "SEARCH" usaria um índice de pesquisa para encontrar esse texto.

A função SEARCH requer dois argumentos:

  • Um nome de índice de pesquisa
  • Uma consulta de pesquisa

A função SEARCH só funciona quando um índice de pesquisa é definido. A função SEARCH pode ser combinada com qualquer construção SQL arbitrária, como filtros, agregações ou mesclagens.

A função SEARCH não pode ser usada com consultas de transação.

A consulta a seguir usa a função SEARCH para retornar todos os álbuns que têm friday ou monday no título:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')

Consulta de pesquisa

A consulta de pesquisa usa a sintaxe de consulta de pesquisa bruta por padrão. É possível especificar sintaxe alternativas usando o argumento dialect.

Dialeto de rquery

O dialeto padrão é a consulta de pesquisa bruta. O Spanner usa uma linguagem específica de domínio (DSL) chamada rquery.

A linguagem rquery segue as mesmas regras do tokenizer de texto simples ao dividir a consulta de pesquisa de entrada em termos distintos. Isso inclui a segmentação de idiomas asiáticos.

Para informações sobre como usar o rquery, consulte Sintaxe do rquery.

dialeto de palavras

O Dialecto de palavras é como o rquery, mas mais simples. Ele não usa operadores especiais. Por exemplo, OR é tratado como um termo de pesquisa em vez de um operador de disjunção. As aspas duplas são tratadas como pontuação em vez de uma pesquisa de frase e são ignoradas.

Com o dialeto de palavras, AND é aplicado implicitamente a todos os termos e é necessário durante a correspondência. Ele segue as mesmas regras do tokenizer de texto simples ao dividir a consulta de pesquisa de entrada em termos.

Para informações sobre como usar o dialeto de palavras, consulte sintaxe de palavras.

words_phrase dialect

O dialeto words_phrase não usa operadores especiais, e todos os termos são tratados como uma frase, o que significa que os termos precisam estar adjacentes e na ordem especificada.

Assim como o rquery, o dialeto words_phrase segue as mesmas regras do tokenizer de texto simples ao dividir a consulta de pesquisa de entrada em termos.

Para saber como usar o dialeto words_phrase, consulte Sintaxe de palavras.

Modo de consulta aprimorado

O Spanner oferece dois modos de pesquisa de texto completo: uma pesquisa básica baseada em token e um modo mais avançado chamado enhance_query. Quando ativado, enhance_query expande a consulta de pesquisa para incluir termos e sinônimos relacionados, aumentando a probabilidade de encontrar resultados relevantes.

Para ativar essa opção, defina o argumento opcional enhance_query=>true na função SEARCH. Por exemplo, a consulta de pesquisa hotl cal corresponde ao álbum Hotel California.

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)

O modo enhance_query é uma opção de consulta. Isso não afeta a tokenização. É possível usar o mesmo índice de pesquisa com ou sem enhance_query.

O Google está sempre melhorando os algoritmos de aprimoramento de consultas. Como resultado, uma consulta com enhance_query == true pode gerar resultados um pouco diferentes ao longo do tempo.

Quando o modo enhance_query está ativado, ele pode aumentar o número de termos que a função SEARCH está procurando, o que pode aumentar um pouco a latência.

Por exemplo, a consulta a seguir usa um tempo limite de três segundos e falha se enhance_query estiver indisponível:

@{require_enhance_query=true, enhance_query_timeout_ms=3000}
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'fast car', enhance_query=>true)

Para mais informações sobre como usar a opção enhance_query, consulte a função SEARCH.

Requisitos de consulta SQL

Há várias condições que uma consulta SQL precisa atender para usar um índice de pesquisa. Se essas condições não forem atendidas, a consulta vai usar um plano de consulta alternativo ou falhar se nenhum plano alternativo existir.

As consultas precisam atender aos seguintes requisitos:

  • As funções SEARCH e SEARCH_SUBSTRING exigem um índice de pesquisa. O Spanner não oferece suporte a essas funções em consultas à tabela base ou aos índices secundários.

  • Os índices particionados precisam ter todas as colunas de partição vinculadas por uma condição de igualdade na cláusula WHERE da consulta.

    Por exemplo, se um índice de pesquisa for definido como PARTITION BY x, y, a consulta precisará ter uma conjunção na cláusula WHERE de x = <parameter or constant> AND y = <parameter or constant>. Esse índice de pesquisa não é considerado pelo otimizador de consulta se essa condição estiver ausente.

  • Todas as colunas TOKENLIST referenciadas pelos operadores SEARCH e SEARCH_SUBSTRING precisam ser indexadas no mesmo índice de pesquisa.

    Por exemplo, considere a seguinte definição de tabela e índice:

    CREATE TABLE Albums (
        AlbumId STRING(MAX) NOT NULL,
        AlbumTitle STRING(MAX),
        AlbumStudio STRING(MAX),
        AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
        AlbumStudio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumStudio)) HIDDEN
      ) PRIMARY KEY(AlbumId);
    
      CREATE SEARCH INDEX AlbumsTitleIndex ON Albums(AlbumTitle_Tokens);
      CREATE SEARCH INDEX AlbumsStudioIndex ON Albums(AlbumStudio_Tokens);
    

    A consulta a seguir falha porque não há um único índice de pesquisa que indexe AlbumTitle_Tokens e AlbumStudio_Tokens:

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, @p1) AND SEARCH(AlbumStudio_Tokens, @p2)
    
  • Se a coluna de ordem de classificação for anulável, o esquema e a consulta precisarão excluir linhas em que a coluna de ordem de classificação for NULL. Para mais detalhes, consulte Ordem de classificação do índice de pesquisa.

  • Se o índice de pesquisa for filtrado por NULL, a consulta precisará incluir a mesma expressão de filtragem por NULL usada em um índice. Consulte Índices de pesquisa filtrados por NULL para mais detalhes.

  • Índices de pesquisa e funções de pesquisa não são compatíveis com DML, DML particionada ou consultas particionadas.

  • Os índices de pesquisa e as funções de pesquisa geralmente são usados em transações somente leitura. Se os requisitos do aplicativo permitirem resultados desatualizados, recomendamos executar consultas de pesquisa com uma duração desatualizada de 10 segundos ou mais. Para mais informações, consulte Ler dados desatualizados. Isso é especialmente útil para consultas de pesquisa grandes que se espalham para vários grupos Paxos.

    Índices de pesquisa e funções de pesquisa não são recomendados em transações de leitura e gravação. Durante a execução, as consultas de pesquisa bloqueiam uma partição de índice inteira. Como resultado, uma taxa alta de consultas de pesquisa em transações de leitura e gravação pode causar conflitos de bloqueio que levam a picos de latência. Por padrão, os índices de pesquisa não são selecionados automaticamente em transações de leitura e gravação. Se uma consulta for forçada a usar um índice de pesquisa em uma transação de leitura e gravação, ela falhará por padrão. Ela também vai falhar se a consulta contiver alguma das funções de pesquisa. Esse comportamento pode ser substituído pela sugestão no nível da instrução @{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE}, mas as consultas ainda estão sujeitas a conflitos de bloqueio.

Depois que as condições de qualificação do índice são atendidas, o otimizador de consulta tenta acelerar as condições de consulta que não são de texto (como Rating > 4). Se o índice de pesquisa não incluir a coluna TOKENLIST adequada, a condição não será acelera e permanecerá como uma condição residual.

Parâmetros de consulta

Os argumentos da consulta de pesquisa são especificados como um literal ou um parâmetro de consulta. Recomendamos o uso de parâmetros de consulta para a pesquisa de texto completo em vez de literais de string quando os argumentos permitem o valor do parâmetro de consulta.

Seleção de índice

O Spanner normalmente seleciona o índice mais eficiente para uma consulta usando a modelagem baseada em custo. No entanto, a sugestão FORCE_INDEX instrui explicitamente o Spanner a usar um índice de pesquisa específico. Por exemplo, o seguinte mostra como forçar o Spanner a usar o AlbumsIndex:

SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")

Se o índice de pesquisa especificado não for qualificado, a consulta vai falhar, mesmo que haja outros índices de pesquisa qualificados.

Snippets nos resultados da pesquisa

Um snippet é um trecho de texto extraído de uma determinada string que dá aos usuários uma noção do que um resultado da pesquisa contém e por que ele é relevante para a consulta.

Por exemplo, o Gmail usa snippets para indicar a parte de um e-mail que corresponde à consulta de pesquisa:

Lista de snippets

O banco de dados gerar um snippet tem várias vantagens:

  1. Conveniência: não é necessário implementar uma lógica para gerar snippets de uma consulta de pesquisa.
  2. Eficiência: os snippets reduzem o tamanho da saída do servidor.

A função SNIPPET cria o snippet. Ele retorna a parte relevante do valor da string original com as posições dos caracteres a serem destacados. O cliente pode escolher como mostrar o snippet para o usuário final (por exemplo, usando texto em negrito ou realçado). A função SNIPPET remove todas as tags HTML da string original.

Por exemplo, o código a seguir usa SNIPPET para extrair texto de AlbumTitle:

SELECT AlbumId, SNIPPET(AlbumTitle, "Fast Car")
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "Fast Car")

A seguir