Joias Com Ou Sem Acento - Joias Tem Acento Ou Nao - FDPLEARN
Joias Tem Acento Ou Nao - FDPLEARN

Como lidar com joias com ou sem acento em catálogos e sistemas

Esse é um daqueles problemas chatos que todo mundo que trabalha com e-commerce de bijuterias ou joias acaba encontrando. Você cadastra um produto como "colares com pingente" e depois na hora de buscar no site o cliente digita "colares com pingente" e não acha nada. Ou pior, você tem duplicatas porque a mesma peça foi cadastrada duas vezes, uma com acento e outra sem.

O problema real com joias com ou sem acento

A questão é que o acento não muda o som da palavra em português, mas muda completamente o código ASCII. "Joia" e "jóia" são a mesma coisa para quem lê, mas para um sistema de busca que compara strings exatas, são dois textos totalmente diferentes. E isso vale para todas as palavras acentuadas: anéis, miçangas, brilhantes, pêndulo, além de termos mais específicos como "rótulo", "próprio", "indicação". Eu já perdi conta de quantas vezes vi um vendedor ter que cadastrar o mesmo produto múltiplas vezes, só para cobrir todas as variações de acentuação. No meu caso, era com um catálogo de correntes de ouro. O sistema da loja não fazia busca semítica, então eu tinha que repetir cada item com e sem acento: "corrente conector", "corrente conector". Dava trabalho e ainda assim deixava passar duplicatas quando o estoque era atualizado automaticamente.

O que funciona na prática é normalizar tudo antes de salvar ou buscar. A normalização remove os acentos e converte para minúsculas, transformando "Miçangas Prateadas" em "miangas prateadas". Aí independente de o cliente digitar com ou sem acento, a busca cai no mesmo registro.

Método de normalização

A abordagem mais simples usa a função unicodedata do Python. Ela converte caracteres acentuados para sua forma decomposta, onde o acento vira um caractere separado que você pode remover. O código básico é:

import unicodedata
def normalizar(texto):
    nfkd = unicodedata.normalize('NFKD', texto)
    sem_acento = nfkd.encode('ASCII', 'ignore').decode('ASCII')
    return sem_acento.lower() Isso converte "jóia" em "jdia", "pêndulo" em "pendulo", "maçã" em "mcaa". A conversão para ASCII ignora os acentos, e o lower() garante consistência nas maiúsculas.

Eu uso esse método há anos e funciona bem para 95% dos casos. O problema é que ele tem limitações. Por exemplo, palavras como "cruzeiro" viram "cruzeio" após a remoção do acento, o que pode causar confusão se você tiver também a palavra "cruzeiro" (sem acento no i) em outro contexto. Não é um problema grave para buscas de produtos, mas vale saber.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Implementação no banco de dados

Se você usa SQL Server, pode criar uma computed column com a versão normalizada e indexar ela. No PostgreSQL, existe a extensão unaccent que faz exatamente isso de forma otimizada. No MySQL, a solução mais prática é manter uma coluna separada para busca, populada automaticamente via trigger ou aplicação. Um detalhe importante: a normalização não deve substituir o texto original. Você guarda "colar com pingente" no campo display e "colar com pingente" no campo search. Assim o cliente vê o texto correto com acentos na tela, mas a busca funciona independente de como digitou.

No meu setup atual, eu uso uma view materializada que roda a normalização toda vez que um produto é inserido ou atualizado. O ganho é que a busca fica muito mais rápida porque o trabalho de normalização já foi feito antecipadamente. Leva cerca de 2 segundos para normalizar 5.000 produtos, mas isso é feito em batch, não on-line.

Falhas comuns e como evitar

Um erro frequente é normalizar apenas na busca, não no cadastro. Se o produto foi cadastrado como "anéis de ouro" e a busca normaliza "aneis de ouro", a comparação direta ainda falha porque o texto armazenado não foi normalizado. A solução é normalizar tanto na entrada quanto na consulta. Outro problema é a perda de informação. Quando você normaliza "sopro" e "ssopro" podem acabar sendo a mesma coisa se a normalização não tratar caracteres dobrados. Isso é raro em português, mas vale verificar se seu vocabulário de produtos tem essas situações.

Para quem não quer implementar normalização, uma alternativa mais simples é usar fuzzy matching. Bibliotecas como-Levenshtein calculam a distância entre strings e permitem encontrar "jóia" mesmo quando o usuário digita "jdia". O problema é que fica mais lento e pode retornar resultados irrelevantes se não tiver um limite de distância bem definido.

Performance e escala

A normalização por string é muito rápida. Em um servidor comum, dá para processar milhões de registros por segundo. O gargalo normalmente é a I/O do banco, não o processamento em si. Se você tem um catálogo grande, considere fazer a normalização em lote durante o deploy, não on-line. Uma prática que eu adotei foi criar um script de migração que normaliza todo o catálogo existente antes de colocar o sistema em produção. Leva uns 10 minutos para 50 mil produtos, mas evita problemas futuros de dados inconsistentes. Depois disso, a normalização passa a ser automática a cada INSERT ou UPDATE.

Se o seu sistema já está em produção e não quer refazer tudo, pelo menos garanta que novos cadastros usem a normalização. Aí você pode rodar a migração dos dados antigos tranquilamente, sem risco de perder vendas por causa de busca quebrada. No final das contas, o assunto "joias com ou sem acento" é mais sobre consistência de dados do que sobre linguística. A regola é simples: normaliza antes de comparar, e testa com os dados reais do seu catálogo, não só com exemplos teóricos. As palavras que mais causam problema costumam ser aquelas com trema ou cedilha, então vale dar atenção especial a elas.