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
