sábado, 25 de junho de 2011

Busca por string semelhantes, mas não iguais

Muitas vezes temos necessidade de procurar por string semelhantes, afinal é muito comum confundir-se entre diferentes grafias para palavras com o mesmo som, como Sousa e Souza.

A função de busca por semelhança mais conhecida em Oracle é SOUNDEX. Utilizando uma base com nomes de navios, posso procurar por nomes semelhantes a Brasil:

select vessel_name, t.cname
  from vessel
      (select 'BRASIL' cname from dual) t
where SOUNDEX(t.cname) = SOUNDEX(upper(vessel_name));


Considerando uma tabela com 52K navios, esta consulta retorna 33 linhas. Alguns nomes são realmente próximos, como Brazil, Brussel e Brazilian Lady. Outros nomes, nem tanto, como Barcelona, Bro Globe e Brooklin. Obviamente todos estes nomes correspondem ao mesmo valor quando aplicada a função SOUNDEX. Devido à implementação do SOUNDEX, todos navios começam com a letra B, pois a inicial deve ser a mesma.

Mas há outra função menos conhecida que pode ser bastante útil: Utl_Match.Edit_Distance_Similarity(s1, s2). A função compara duas strings e retorna o grau de similaridade entre elas, sempre um valor entre 0 e 100.

A query

select vessel_name, t.cname, utl_match.edit_distance_similarity(t.cname, upper(vessel_name)) simil
  from vessel,
      (select 'BRASIL' cname from dual) t
where utl_match.edit_distance_similarity(t.cname, upper(vessel_name)) > 50;

retorna 21 linhas, todas bastante similares (por que o valor deve ser maior que 50%), como Basil, Orasila e Hasil. É fácil notar que a primeira letra pode ser diferente, tornando a busca bem mais flexível.

Alterando o grau de similaridade, a query retorna um número diferente de linhas. Se o grau de similaridade for igual a 70, a consulta retorna 3 linhas apenas. Se for igual a 30, retorna 2156 linhas. No limite, grau de similaridade igual a 100 retorna somente valores exatamente iguais. Grau de similaridade igual a zero, retornaria todas as linhas da tabela.

Em um projeto que estou trabalhando, decidimos usar esta função exatamente porque o grau de similaridade pode ser um parâmetro na interface da aplicação ajustado pelo usuário, tornando as buscas mais flexíveis.

Um comentário: