Nesta página, descrevemos como usar o refinamento de consultas como parte de uma pesquisa de texto completo.
Para aumentar a probabilidade de encontrar resultados relevantes, o Spanner oferece recursos avançados que expandem a consulta de pesquisa para incluir termos relacionados, sinônimos e correções ortográficas. O Spanner oferece as seguintes opções para melhorar as consultas:
Consulta aprimorada
Para usar a consulta avançada, defina enhance_query=>true na função SEARCH. Em seguida, o Spanner expande automaticamente as consultas de pesquisa incluindo termos relacionados e sinônimos, aplicando a derivação e fazendo correções ortográficas. Por exemplo, ao usar a consulta avançada, a consulta de pesquisa hotl cal corresponde ao álbum Hotel California.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)
PostgreSQL
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'hotl cal', enhance_query=>true)
enhance_query é uma opção de tempo de consulta que não afeta a tokenização.
É possível usar o mesmo índice de pesquisa com ou sem enhance_query.
O Google está sempre aprimorando os algoritmos de refinamento de consultas. Como resultado, uma consulta com enhance_query => true pode gerar resultados ligeiramente diferentes ao longo do tempo.
Quando enhance_query é usado, a latência pode aumentar devido à sobrecarga de expandir a consulta de pesquisa e executar a consulta maior resultante.
Dicionários personalizados
É possível usar dicionários personalizados com a pesquisa de texto completo do Spanner para definir sinônimos de termos no seu conjunto de dados. Isso é útil para capturar sinônimos, acrônimos, termos equivalentes e outras variações de palavras para melhorar a recuperação dos resultados da pesquisa.
Criar uma tabela de dicionário personalizado
Um dicionário personalizado é uma tabela criada pelo usuário que contém pares de chave-valor de termos e sinônimos. Para criar um, inclua a opção fulltext_dictionary_table = true na instrução CREATE TABLE. A tabela precisa ter duas colunas:
Key: uma coluna de string não anulável para o termo a ser expandido com sinônimos.Value: uma coluna de matriz de strings não anulável para uma matriz de sinônimos da chave.
Não pode haver outras colunas além de Key e Value na tabela.
Se um termo de pesquisa corresponder a um Key no dicionário, a pesquisa será expandida para incluir todos os sinônimos correspondentes em Value, além do próprio termo principal.
No exemplo a seguir, criamos uma tabela de dicionário personalizada chamada MyCustomDictionary. Você também precisa definir a opção de tabela fulltext_dictionary_table=true durante a criação.
GoogleSQL
CREATE TABLE MyCustomDictionary (
Key STRING(MAX) NOT NULL,
Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (fulltext_dictionary_table = true);
PostgreSQL
CREATE TABLE mycustomdictionary (
key character varying NOT NULL,
value character varying [] NOT NULL,
PRIMARY KEY(key)
) WITH ( type = 'fulltext_dictionary')
Depois de criar a tabela, insira os sinônimos:
GoogleSQL
INSERT INTO MyCustomDictionary (Key, Value) VALUES
('album', ['vinyl', 'cassette']),
('edm', ['electronic dance music']);
PostgreSQL
INSERT INTO mycustomdictionary (key, value) VALUES
('album', ARRAY['vinyl', 'cassette']),
('edm', ARRAY['electronic dance music']);
Ao preencher a tabela, lembre-se do seguinte:
- As chaves precisam ser palavras únicas.
- Os valores podem ser palavras únicas ou frases. Se um valor tiver várias palavras, ele será tratado como uma pesquisa de frase durante a expansão de consulta.
- Todas as chaves e valores precisam estar em letras minúsculas. Isso garante que eles correspondam aos tokens de pesquisa, que são convertidos em letras minúsculas pelo tokenizador padrão.
A expansão da pesquisa só ocorre quando um termo de pesquisa corresponde a um Key. Se um termo de pesquisa corresponder a um sinônimo em Value, mas não a um Key, a pesquisa não será expandida. Se você precisar de um mapeamento bidirecional (por exemplo, para que a pesquisa por vinyl ou cassette também encontre album), insira mapeamentos inversos na tabela de dicionário. O exemplo a seguir mostra como inserir mapeamentos bidirecionais para album, vinyl e cassette:
GoogleSQL
INSERT INTO MyCustomDictionary (Key, Value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ['album']
FROM UNNEST(['vinyl', 'cassette']) AS syn;
PostgreSQL
INSERT INTO mycustomdictionary (key, value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ARRAY['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ARRAY['album']
FROM unnest(ARRAY['vinyl', 'cassette']) AS syn;
Usar um dicionário personalizado em consultas de pesquisa
Para usar um dicionário personalizado, especifique o nome da tabela de dicionário no argumento dictionary da função SEARCH.
Se um termo de pesquisa for uma chave no dicionário,
SEARCHtambém vai procurar os valores dela. O termoalbumcorresponde a mensagens que contêmvinyloucassette.GoogleSQL
SELECT MessageId, Body FROM Messages WHERE SEARCH(Body_Tokens, 'album', dictionary=>'MyCustomDictionary');PostgreSQL
SELECT messageid, body FROM messages WHERE spanner.search(body_tokens, 'album', dictionary=>'mycustomdictionary');Quando um valor de dicionário contém várias palavras, como
electronic dance musicpara a chaveedm, ele é tratado como uma pesquisa de frase. Isso significa que os termos precisam aparecer adjacentes e na ordem exata especificada para serem considerados uma correspondência. Por exemplo, a consulta a seguir retorna resultados que contêm a frase exata "música eletrônica", mas não "música eletrônica de dança". Isso é útil principalmente para expandir acrônimos e pode ser usado da seguinte maneira:GoogleSQL
SELECT MessageId, Body FROM Messages WHERE SEARCH(Body_Tokens, 'edm', dictionary=>'MyCustomDictionary');PostgreSQL
SELECT messageid, body FROM messages WHERE spanner.search(body_tokens, 'edm', dictionary=>'mycustomdictionary');
Desatualização da pesquisa no dicionário
Por padrão, as entradas do dicionário personalizado são lidas com uma defasagem máxima de 15 segundos. Isso reduz a sobrecarga da operação de leitura, porque ler dados com alguma defasagem é mais eficiente do que ler os dados mais atuais. Por isso, as mudanças nas entradas do dicionário podem levar até 15 segundos para aparecer nas consultas de pesquisa. É possível substituir esse comportamento das seguintes maneiras:
- Usando a opção de tabela
fulltext_dictionary_staleness. - Usando a dica de consulta
fulltext_dictionary_stalenesspara um controle mais granular.
A dica de consulta substitui a opção de tabela se ambas forem usadas.
Opção de tabela fulltext_dictionary_staleness
É possível definir a opção fulltext_dictionary_staleness para a tabela de dicionário. Todas as consultas que usam essa tabela de dicionário usam esse valor de defasagem, a menos que sejam substituídas pela dica de consulta.
GoogleSQL
O exemplo a seguir mostra como CREATE uma tabela com a opção fulltext_dictionary_staleness:
CREATE TABLE MyCustomDictionary (
Key STRING(MAX) NOT NULL,
Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (
fulltext_dictionary_table = true,
fulltext_dictionary_staleness = '5s'
);
O exemplo a seguir mostra como ALTER a tabela para mudar ou definir a opção fulltext_dictionary_staleness:
ALTER TABLE MyCustomDictionary SET OPTIONS (
fulltext_dictionary_staleness = '60s'
);
PostgreSQL
O exemplo a seguir mostra como CREATE uma tabela com a opção fulltext_dictionary_staleness:
-- Create with 5s staleness
CREATE TABLE mycustomdictionary (
key character varying NOT NULL,
value character varying[] NOT NULL,
PRIMARY KEY(key)
) WITH (
type = 'fulltext_dictionary',
fulltext_dictionary_staleness = '5s'
);
A Interface PostgreSQL não é compatível com a tabela ALTER para mudar ou definir a opção fulltext_dictionary_staleness.
fulltext_dictionary_staleness dica de consulta
Para um controle mais granular, use a dica de consulta fulltext_dictionary_staleness para especificar uma defasagem diferente para uma consulta individual. Essa dica substitui a configuração no nível da tabela.
O exemplo a seguir usa uma dica para realizar pesquisas na tabela de dicionário com inatividade zero. Isso garante que as entradas de dicionário mais atuais sejam lidas. Essa abordagem pode aumentar a latência da consulta porque a leitura dos dados mais atuais é menos eficiente do que permitir alguma defasagem.
GoogleSQL
@{fulltext_dictionary_staleness="0s"}
SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'Bill', dictionary=>'MyCustomDictionary');
PostgreSQL
/*@ fulltext_dictionary_staleness='0s' */
SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'Bill', dictionary=>'mycustomdictionary');
Limitações conhecidas com tabelas de dicionário personalizadas
- O suporte para usar a importação e exportação do Spanner com tabelas de dicionário personalizadas é limitado.
- As tabelas de dicionário personalizadas precisam ser criadas no esquema padrão e não podem ser criadas em esquemas nomeados.
- As tabelas de dicionário personalizado são compatíveis apenas com o dialeto de consulta SEARCH padrão.
Como combinar dicionários personalizados com consultas aprimoradas
É possível combinar sinônimos do dicionário personalizado com enhanced query definindo dictionary e enhance_query=>true na função SEARCH. A melhoria de consultas pode expandir as consultas com sinônimos comuns ou correções ortográficas, enquanto os dicionários personalizados permitem definir suas próprias expansões. Por exemplo, se enhance_query expandir album para incluir record e MyCustomDictionary mapear album para ['vinyl', 'cassette'], a consulta a seguir vai corresponder a mensagens que contenham album, record, vinyl ou cassette:
GoogleSQL
SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'album', enhance_query=>true, dictionary=>'MyCustomDictionary');
PostgreSQL
SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'album', enhance_query=>true, dictionary=>'mycustomdictionary');
Quando os dois recursos estão ativados, eles operam de forma independente nos termos de pesquisa originais, e os termos gerados por um recurso não são usados como entrada para o outro.
A seguir
- Saiba como encontrar correspondências aproximadas com a pesquisa difusa.
- Saiba como classificar os resultados da pesquisa.