Se você deseja otimizar correspondências de substring arbitrárias, uma opção é usar o
pg_tgrm
módulo
. Adicione um índice:CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
Isso quebrará "Simple Cafe" em "sim", "imp", "mpl", etc., e adicionará uma entrada ao índice para cada trigam em cada linha. O planejador de consulta pode usar automaticamente esse índice para correspondências de padrão de substring, incluindo:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
Essa consulta procurará "caf" e "afe" no índice, encontrará a interseção, buscará essas linhas e verificará cada linha em relação ao seu padrão. (Essa última verificação é necessária, pois a interseção de "caf" e "afe" corresponde a "simples café" e "inseguro scaffolding", enquanto "%cafe%" deve corresponder apenas a um). O índice se torna mais eficaz à medida que o padrão de entrada fica mais longo, pois pode excluir mais linhas, mas ainda não é tão eficiente quanto indexar palavras inteiras, portanto, não espere uma melhoria de desempenho em relação a
to_tsvector
. O problema é que os trigramas não funcionam para padrões com menos de três caracteres. Isso pode ou não ser um fator decisivo para sua aplicação.
Editar: Eu inicialmente adicionei isso como um comentário.
Eu tive outro pensamento ontem à noite quando eu estava quase dormindo. Faça um
cjk_chars
função que recebe uma string de entrada, regexp_matches
todos os intervalos CJK Unicode e retorna uma matriz de quaisquer desses caracteres ou NULL
se nenhum. Adicione um índice GIN em cjk_chars(location_name)
. Em seguida, consulte:WHERE CASE
WHEN cjk_chars('query') IS NOT NULL THEN
cjk_chars(location_name) @> cjk_chars('query')
AND location_name LIKE '%query%'
ELSE
<tsvector/trigrams>
END
Ta-da, unigramas!