A extensão zhparser habilita a busca de texto completo em chinês no ApsaraDB RDS for PostgreSQL. Diferentemente do inglês, o texto em chinês não possui espaços entre as palavras, o que impede o parser nativo do PostgreSQL de segmentá-lo corretamente. O zhparser segmenta o texto chinês com base na semântica, permitindo indexação e busca de texto completo precisas.
Pré-requisitos
Antes de começar, verifique se:
A instância RDS executa o PostgreSQL 10 ou posterior
A versão secundária do mecanismo é 20230830 ou posterior. Para o PostgreSQL 17, a versão secundária do mecanismo deve ser 20241030 ou posterior
O parâmetro
shared_preload_librariesda instância incluizhparser. Para obter instruções, consulte Modificar os parâmetros de uma instância do ApsaraDB RDS for PostgreSQL
Extensões novas ou recriadas exigem a versão secundária do mecanismo 20230830 ou posterior. Caso sua instância execute uma versão anterior, atualize-a antes de criar a extensão. Consulte Atualizar a versão secundária do mecanismo. Se a extensão já estiver instalada em uma versão mais antiga, ela continuará funcionando normalmente. Para mais informações, consulte [[Alterações de produto/recurso] Limites na criação de extensões para instâncias do ApsaraDB RDS for PostgreSQL](https://www.alibabacloud.com/help/en/rds/apsaradb-rds-for-postgresql/limits-on-the-creation-of-the-pg-cron-extension).
Ativar o zhparser
Execute os comandos a seguir para criar a extensão e definir uma configuração de busca de texto chamada testzhcfg:
CREATE EXTENSION zhparser;
CREATE TEXT SEARCH CONFIGURATION testzhcfg (PARSER = zhparser);
ALTER TEXT SEARCH CONFIGURATION testzhcfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;
-- Optional: enable short-word compounding for more granular segmentation
ALTER ROLE CURRENT_ROLE SET zhparser.multi_short=on;
A linha ADD MAPPING FOR n,v,a,i,e,l associa seis tipos principais de tokens (n, v, a, i, e, l) ao dicionário simple.
Verificar a segmentação
A busca de texto completo do PostgreSQL utiliza três funções essenciais:
|
Função |
Finalidade |
Exemplo de entrada → saída |
|
|
Retorna tokens brutos com seus IDs de tipo |
Tokens brutos gerados pelo parser |
|
|
Converte texto em lexemas normalizados para indexação |
Texto → lista de lexemas indexados |
|
|
Transforma uma frase em uma expressão de consulta |
Frase → consulta para comparação com um |
Para confirmar se o zhparser segmenta o texto adequadamente, execute as consultas de teste a seguir:
-- Test raw token output
-- Returns a (tokid, token) result set, where tokid identifies the token type
SELECT * FROM ts_parse('zhparser', 'hello world! 2010年保障房建设在全国范围内获全面启动,从中央到地方纷纷加大 了 保 障 房 的 建 设 和 投 入 力 度 。 2011年,保障房进入了更大规模的建设阶段。 住房城乡建设部党组书记、部长姜伟新去年底在全国住房城乡建设工作会议上表示,要继续推进保障性安居工程建设。 ');
-- Convert text to a tsvector (normalized lexeme list used for indexing)
SELECT to_tsvector('testzhcfg','"今年保障房新开工数量虽然有所下调,但实际的年度在建规模以及竣工规模会超以往年份,相对应的对资金的需求也会创历史纪录。"陈国强说。 在他看来,与2011年相比,2012年的保障房建设在资金配套上的压力将更为严峻。 ');
-- Convert a search phrase to a tsquery for use with the @@ operator
SELECT to_tsquery('testzhcfg', '保障房资金压力');
Criar um índice de texto completo e executar consultas
Após ativar o zhparser, crie um índice GIN (Generalized Inverted Index) na coluna desejada para busca. O exemplo a seguir cria um índice de texto completo na coluna name da tabela t1:
-- Replace t1 and name with your actual table name and column name
CREATE INDEX idx_t1 ON t1 USING gin (to_tsvector('testzhcfg', upper(name)));
Use o operador @@ para comparar linhas com uma consulta de busca:
SELECT * FROM t1 WHERE to_tsvector('testzhcfg', upper(t1.name)) @@ to_tsquery('testzhcfg', '(防火)');
Tanto o índice quanto a cláusula WHERE devem usar a mesma expressão — to_tsvector('testzhcfg', upper(name)) — para que o PostgreSQL possa utilizar o índice durante a execução da consulta.
Adicionar segmentos de palavras personalizados
Caso precise incluir termos específicos de domínio que o dicionário padrão não segmenta corretamente, insira-os em pg_ts_custom_word.
O exemplo a seguir adiciona 保障房资 como um único segmento de palavra:
-- Check the current segmentation result
SELECT to_tsquery('testzhcfg', '保障房资金压力');
-- Add the new word segment
INSERT INTO pg_ts_custom_word VALUES ('保障房资');
-- Sync the dictionary to apply the change
SELECT zhprs_sync_dict_xdb();
-- Reconnect to the database (the new session picks up the updated dictionary)
\c
-- Verify the new segmentation result
SELECT to_tsquery('testzhcfg', '保障房资金压力');
Sempre que adicionar, remover ou alterar segmentos de palavras, chame zhprs_sync_dict_xdb() e reconecte-se ao banco de dados para aplicar as modificações. As alterações não afetam sessões já abertas.
Limites do dicionário personalizado
|
Limite |
Valor |
|
Quantidade máxima de segmentos de palavras personalizados |
1.000.000 |
|
Tamanho máximo por segmento de palavra |
128 bytes |
Se a quantidade de segmentos ultrapassar 1.000.000, os excedentes serão ignorados. Segmentos com mais de 128 bytes são truncados no byte 128.
O dicionário personalizado e o dicionário interno funcionam simultaneamente.