Achei a página original do código. Dá para ver que eu não fiz muita
coisa além de colocar uns translates bestas.

http://www.mloyola.com.br/site/busca-fonetica-postgresql

Menção honrosa para o Marcus Loyola que foi quem disponibilizou o
código original.

Em 10 de julho de 2013 14:50, Pablo Sánchez <[email protected]> escreveu:
> Alguém tem idéia de como eu faço para mandar essa contribuição para o
> pessoal do Postgres para que tenhamos lá um suporte para soundex para
> latin? E alguém tem idéias para acrescentar, já que eu só fiz um pouco
> de nada que já me resolve horrores aqui, mas que com certeza não é nem
> 10% do total para fechar com chave de ouro esse código?
>
> Em 10 de julho de 2013 14:45, Pablo Sánchez <[email protected]> escreveu:
>> Já resolvi aqui a questão.
>>
>> Segue o que eu implementei com base em um código que encontrei na Net
>> (mas fechei a aba e estava em modo anônimo, perdi qual era - créditos
>> para outra pessoa).
>>
>> Coloquei o peso do Ç igual ao peso de C que é igual ao peso de S e de
>> X e coloquei o ÃO e ÕE com o peso de M caso o cara tenha escrito um
>> JOAUM ao invés de JOÃO.
>>
>> Só respondendo: não quero ser muito flexível, por isso eliminei uma
>> penca de coisas e deixei o índice apenas como <= 1. E sim, o cadastro
>> de detentos é sempre feito com o nome completo. Só para te dar uma
>> base de como ficou bacana, o teste foi assim:
>>
>> SELECT LATINEX('Joaum Culioins da Çilva Roxa'), LATINEX('João Culhões
>> da Silva Rocha');
>>
>> Veja que a assinatura de ambos é idêntica.
>>
>> Meu problema está apenas com o raio da letra W que pode ter som de V
>> ou se U como em Wallace e Watson. Nesse caso a assinatura de todo o
>> restante é idêntica, exceto a primeira letra. Não posso descartar, mas
>> posso colocar uma margem de 1 se eu simplesmente pegar os resultados
>> como parte de levenschtein e manter o índice em <= 1. Acredito que
>> isso me ajude também a pegar similaridades como Jasmin e Yasmin.
>>
>> Assim, eis o que eu tenho:
>>
>> -- Resultado levenshtein = 0, porque o primeiro caractere é idêntico
>> SELECT LEVENSHTEIN(LATINEX('Joaum Culioins da Çilva Roxa'),
>> LATINEX('João Culhões da Silva Rocha'))
>>
>> -- Resultados levenshtein = 1, porque o primeiro caractere é o único que
>> SELECT LEVENSHTEIN(LATINEX('Uólaci Culioins da Çilva Roxa'),
>> LATINEX('Wallace Culhões da Silva Rocha'))
>> SELECT LEVENSHTEIN(LATINEX('Wanezza Culioins da Çilva Roxa'),
>> LATINEX('Vanessa Culhões da Silva Rocha'))
>> SELECT LEVENSHTEIN(LATINEX('Amiltão Culioins da Çilva Roxa'),
>> LATINEX('Hamilton Culhões da Silva Rocha'))
>>
>> --Criação da função de peso do som das consoantes para cálculo de soundex 
>> latin
>>
>> CREATE OR REPLACE FUNCTION pesom(CHARACTER)
>>  RETURNS INTEGER AS
>> $BODY$
>>
>> SELECT
>>     CASE $1
>>       WHEN 'B' THEN 1
>>       WHEN 'C' THEN 2
>>       WHEN 'D' THEN 3
>>       WHEN 'F' THEN 1
>>       WHEN 'G' THEN 2
>>       WHEN 'J' THEN 2
>>       WHEN 'K' THEN 2
>>       WHEN 'L' THEN 4
>>       WHEN 'M' THEN 5
>>       WHEN 'N' THEN 5
>>       WHEN 'P' THEN 1
>>       WHEN 'Q' THEN 2
>>       WHEN 'R' THEN 6
>>       WHEN 'S' THEN 2
>>       WHEN 'T' THEN 3
>>       WHEN 'V' THEN 1
>>       WHEN 'X' THEN 2
>>       WHEN 'Z' THEN 2
>>       ELSE 0
>> END
>>
>> $BODY$
>> LANGUAGE 'sql' VOLATILE
>> COST 100;
>>
>> ALTER FUNCTION pesom(CHARACTER) OWNER TO postgres;
>>
>>
>> --Criação da função de peso do som das consoantes para cálculo de soundex 
>> latin
>>
>>
>> CREATE OR REPLACE FUNCTION latinex(CHARACTER VARYING)
>> RETURNS CHARACTER AS
>> $BODY$
>>
>> DECLARE
>> texto VARCHAR;
>> resultado VARCHAR;
>> i INT;
>> ipesom INT;
>> valorPrimeiraLetra INT;
>>
>> BEGIN
>>
>> texto = $1;
>> texto = UPPER(texto);
>> texto = TRANSLATE(texto, 'ãO', 'M');
>> texto = TRANSLATE(texto, 'ÃO', 'M');
>> texto = TRANSLATE(texto, 'õE', 'M');
>> texto = TRANSLATE(texto, 'ÕE', 'M');
>> texto = TRANSLATE(texto, 'ñ', 'N');
>> texto = TRANSLATE(texto, 'Ñ', 'N');
>> texto = TRANSLATE(texto, 'ç', 'C');
>> texto = TRANSLATE(texto, 'Ç', 'C');
>>
>> resultado = SUBSTRING(texto,1,1);
>>
>> valorPrimeiraLetra = pesom(resultado);
>>
>> i=2;
>>
>>
>> WHILE i < LENGTH(texto) LOOP
>>
>> ipesom = pesom(SUBSTRING(texto, i, 1));
>>
>> IF (NOT (ipesom = 0) AND NOT (valorPrimeiraLetra = ipesom)) THEN
>> resultado = resultado || ipesom;
>> END IF;
>>
>> valorPrimeiraLetra = ipesom;
>>
>> ipesom = 0;
>>
>> i := i + 1;
>>
>> END LOOP;
>>
>> WHILE LENGTH(resultado) < 4 LOOP
>> resultado = resultado || '0';
>> END LOOP;
>>
>> RETURN resultado;
>>
>> END;
>>
>> $BODY$
>> LANGUAGE 'plpgsql' VOLATILE
>> COST 100;
>>
>> ALTER FUNCTION latinex(CHARACTER VARYING) OWNER TO postgres;
>>
>> Em 10 de julho de 2013 11:13, Euler Taveira <[email protected]> escreveu:
>>> On 10-07-2013 10:23, Pablo Sánchez wrote:
>>>> Até o momento, tudo quase ok (tirando o fato de que não é para idiomas
>>>> latinos, mas já é algo). Só que fiquei com dúvida sobre qual seria um
>>>> bom valor para o índice Levenshtein. Estou extremamente compelido pelo
>>>> índice 3, mas gostaria de opiniões.
>>>>
>>> Não existe índice bom ou ruim; tudo depende de (i) seus dados e (ii) o
>>> quão flexível você quer ser. Faça bastante testes em uma "baseline" e
>>> decida qual é o ideal.
>>>
>>>> Eis um exemplo de teste que mostrou-se satisfatório
>>>>
>>>> select soundex('Josefa Silva'), soundex('Joseph Silva');
>>>> select levenshtein('Josefa Silva', 'Joseph Silva');
>>>> select metaphone('Josefa Silva', 10), metaphone('Joseph Silva', 10);
>>>> select dmetaphone('Josefa Silva'), dmetaphone('Joseph Silva');
>>>> select dmetaphone_alt('Josefa Silva'), dmetaphone_alt('Joseph Silva');
>>>>
>>> Eu não aconselharia utilizar qualquer dessas funções em nomes completos.
>>> O soundex, por exemplo, considera somente algumas posições (no mínimo 4
>>> caracteres). O levenshtein utilizado com strings longas podem ter mais
>>> do que 3 ou 4 mudanças. Ao invés disso, quebre o nome completo em nome e
>>> sobrenome e faça uma comparação individual ou utilize uma composição de
>>> funções de similaridade.
>>>
>>> Se você quer usar funções por similaridade, eu aconselho dar uma olhada
>>> no pg_similarity [1]. Ele contém uma série de funções que podem te
>>> auxiliar na tarefa de casamento flexível de strings.
>>>
>>>
>>> [1] https://github.com/eulerto/pg_similarity
>>>
>>>
>>> --
>>>    Euler Taveira                   Timbira - http://www.timbira.com.br/
>>>    PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento
>>> _______________________________________________
>>> pgbr-geral mailing list
>>> [email protected]
>>> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>>
>>
>>
>> --
>>
>>
>>
>>
>>
>> Pablo Santiago Sánchez
>> ZCE ZEND006757
>> [email protected]
>> (61) 9975-0883
>> http://www.sansis.com.br
>> "Pluralitas non est ponenda sine necessitate"
>
>
>
> --
>
>
>
>
>
> Pablo Santiago Sánchez
> ZCE ZEND006757
> [email protected]
> (61) 9975-0883
> http://www.sansis.com.br
> "Pluralitas non est ponenda sine necessitate"



-- 





Pablo Santiago Sánchez
ZCE ZEND006757
[email protected]
(61) 9975-0883
http://www.sansis.com.br
"Pluralitas non est ponenda sine necessitate"
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a