AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 208070
Accepted
Victor
Victor
Asked: 2018-05-29 12:48:55 +0800 CST2018-05-29 12:48:55 +0800 CST 2018-05-29 12:48:55 +0800 CST

Manter as versões acentuadas e não acentuadas em uma coluna tsvector? [duplicado]

  • 772
Essa pergunta já tem resposta aqui :
Criando uma pesquisa que não diferencia maiúsculas de minúsculas e não diferencia acentos/diacríticos em um campo (1 resposta)
Fechado há 4 anos .

Estou enfrentando uma situação em que os usuários DEVEM enviar itens escritos em inglês simples. No entanto, acontece que os nomes têm acentos - vindos de vários idiomas. Eu tenho uma tsvectorcoluna na minha tabela que é indexada para pesquisa de texto completo.

Aqui estão as informações sobre esta coluna e informações relevantes sobre a tabela:

                                                         Table "public.companies"
     Column     |          Type          |                       Modifiers                        | Storage  | Stats target | Description 
----------------+------------------------+--------------------------------------------------------+----------+--------------+-------------
 id             | integer                | not null default nextval('companies_id_seq'::regclass) | plain    |              | 
 name           | character varying(128) | not null                                               | extended |              | 
 description    | text                   |                                                        | extended |              | 
 tsmeta         | tsvector               |                                                        | extended |              | 

Indexes:
    "companies_pkey" PRIMARY KEY, btree (id) CLUSTER
    "companies_search_idx" gin (tsmeta)
Triggers:
    companies_tsmeta_update BEFORE INSERT OR UPDATE ON companies FOR EACH ROW EXECUTE PROCEDURE companies_tsmeta_trigger()

Agora o problema vem quando o usuário cria um nome como français . Nem todos os usuários têm o caractere ç em mãos e aqueles que não têm terão problemas para encontrar essa entrada - o que significa que ela será armazenada com o cedilla-c na tsvectorcoluna. Então meu pensamento foi usar a unaccentextensão para tirar esses acentos. Porém agora os usuários que apenas digitarem français terão problemas e não encontrarão a entrada. Então eu criei uma função que apenas concatena as duas versões (acentuadas e sem acentos) do nome e das descrições. No entanto, as descrições podem ficar muito grandes e eu me preocupo que o índice leve muito armazenamento.

create or replace function companies_tsmeta_trigger() returns trigger as $$
begin
  new.tsmeta :=
    setweight(to_tsvector('english', coalesce(new.name, '')), 'A') ||
    setweight(to_tsvector('english', unaccent(coalesce(new.name, ''))), 'B') ||
    setweight(to_tsvector('english', coalesce(new.description, '')), 'C') ||
    setweight(to_tsvector('english', unaccent(coalesce(new.description, ''))), 'D');
  return new;
end;
$$ language plpgsql;

Quais são suas sugestões?

postgresql index
  • 1 1 respostas
  • 1555 Views

1 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2018-05-30T16:44:17+08:002018-05-30T16:44:17+08:00

    Meu primeiro impulso foi este: Use um índice de expressão apenas nas strings não acentuadas . Não armazene tsmetana tabela de forma redundante. Então você também não precisa do gatilho. E certamente não inchar o índice com string original e sem acento. Dessa forma, sua tabela e índice são menores e mais rápidos em leitura e gravação.

    No entanto , a expressão de índice precisa ser IMMUTABLE. setweight()e to_tsvector(regconfig,text)são IMMUTABLE, isso é bom. Mas unaccent()é só STABLE. Leia a avaliação detalhada aqui primeiro:

    • O PostgreSQL suporta agrupamentos “insensíveis ao acento”?

    Se você tiver vários casos de uso, crie o wrapper de função f_unaccent()conforme as instruções.

    Para o caso em questão, podemos envolver toda a tsvectorcriação em uma única IMMUTABLEfunção:

    CREATE OR REPLACE FUNCTION f_tsmeta(_a text, _b text)
      RETURNS tsvector AS
    $func$
      SELECT setweight(to_tsvector('english', public.unaccent('public.unaccent', _a)), 'A')
          || setweight(to_tsvector('english', public.unaccent('public.unaccent', COALESCE(_b, ''))), 'B')
    $func$  LANGUAGE sql IMMUTABLE;
    

    Supondo que o módulo adicional unaccentesteja instalado no esquema public, conforme explicado na resposta vinculada.

    Como nameé definido NOT NULL, não precisamos COALESCEdessa coluna.

    Então o índice pode ficar assim:

    CREATE INDEX companies_search_idx ON companies USING gin (f_tsmeta(name, description));
    

    Usado em consultas como:

    SELECT * FROM companies
    WHERE f_tsmeta(name, description) @@ to_tsquery('english', 'foo');
    

    Pensando bem, os pesos não são incluídos em um índice GIN. Portanto, pode valer a pena incluir o valor pré-calculado na tabela. O manual:

    Os índices GIN armazenam apenas as palavras (lexemas) de tsvectorvalores, e não seus rótulos de peso. Assim, uma nova verificação de linha da tabela é necessária ao usar uma consulta que envolve pesos.

    Com o índice de expressão demonstrado, a expressão deve ser reavaliada ao usar pesos, o que adiciona um custo extra.

    Coluna redundante ou índice de expressão, deve ser uma melhoria integrar o dicionário unaccent TEXT SEARCH CONFIGURATIONdiretamente em um índice personalizado (e coluna da tabela) usando isso, conforme demonstrado por Evan nesta resposta relacionada:

    • Criando uma pesquisa que não diferencia maiúsculas de minúsculas e não diferencia acentos/diacríticos em um campo

    Simplifica as coisas e deve ser mais eficiente.

    • 3

relate perguntas

  • Quanto "Padding" coloco em meus índices?

  • Sequências Biológicas do UniProt no PostgreSQL

  • O que significa "índice" em RDBMSs? [fechado]

  • Como criar um índice condicional no MySQL?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve