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" _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
