Webly: Busca Diferente Usando A Função Soundex - Webly

Ir para

Regras para postagem no fórum

É permitido postar livremente respostas com comentários, testes e avaliações dos scripts. Postagens contendo dúvidas sobre o script, deverão ser postadas no fórum principal de ASP.

IMPORTANTE: Todos os tutoriais postados neste fórum irão automaticamente para o portal Webly. Contribua você também e faça parte da equipe de colaboradores que fazem a evolução da web. Obrigado.
Página 1 de 1

Busca Diferente Usando A Função Soundex Inicialmente o codigo para Mysql, mas dá pra adaptar em outros DBs Avaliar tópico: ****- 1 Votos

#1 Membro offline   jonathan Ícone

  • Ícone
  • Grupo: Membros
  • Posts: 40
  • Cadastrado: 04-outubro 06
  • Localização:Porto Alegre - RS

Postou 17 fevereiro 2008 - 04:46

Que tal oferecer em seu site uma busca que varre todos os módulos do site exibindo rudoe m um único resultado?
Além disso sugere ao usuário os links prováveis de acordo com as palavras digitadas.
Essa primeira versão fiz para o banco MySql, mas pode ser usada em outros bancos bastando pequenas modificações no SQL.

A partir desta estrutura é possível criar as tags mais populares

A inclusão desta funcionlidade se resume a uma pequena alteração nas páginas de cadastro e edição dos itens administráveis do seu site.

Na url de exemplo pesquise por "carro" ou "IPVA" ou "carro ipva" ou "horrario carro ipva"(perceba que a palavra Horário está escrita errada de propósito) e veja a diferença na exibição da consulta
URL Exemplo: http://allmarketweb....busca/busca.asp

Caso queira baixar o exemplo da Url acima acesse http://www.allmarket...amp;idCategoria= e baixe os arquivos

-- MySQL Administrator dump 1.4
--
-- ------------------------------------------------------
-- Server version 5.0.27-community-nt


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;


--
-- Create schema db_jonathandj
--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_jonathandj;
USE db_jonathandj;

--
-- Table structure for table `db_jonathandj`.`jdj_modulo`
--

DROP TABLE IF EXISTS `jdj_modulo`;
CREATE TABLE `jdj_modulo` (
  `idModulo` int(10) unsigned NOT NULL auto_increment,
  `tabela` varchar(45) NOT NULL default '',
  `id` varchar(45) NOT NULL default '',
  `pagina` varchar(45) NOT NULL default '',
  `titulo` varchar(45) NOT NULL default '',
  `modulo` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`idModulo`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `db_jonathandj`.`jdj_modulo`
--

/*!40000 ALTER TABLE `jdj_modulo` DISABLE KEYS */;
INSERT INTO `jdj_modulo` (`idModulo`,`tabela`,`id`,`pagina`,`titulo`,`modulo`) VALUES 
 (1,'noticia','idNoticia','noticia.asp?idNoticia=','tituloNoticia','Notícias'),
 (2,'produto','idProduto','produto.asp?idProduto=','nomeProduto','Produtos');
/*!40000 ALTER TABLE `jdj_modulo` ENABLE KEYS */;


--
-- Table structure for table `db_jonathandj`.`jdj_palavra`
--

DROP TABLE IF EXISTS `jdj_palavra`;
CREATE TABLE `jdj_palavra` (
  `idPalavra` int(10) unsigned NOT NULL auto_increment,
  `palavra` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`idPalavra`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `db_jonathandj`.`jdj_palavra`
--

/*!40000 ALTER TABLE `jdj_palavra` DISABLE KEYS */;
/*!40000 ALTER TABLE `jdj_palavra` ENABLE KEYS */;


--
-- Table structure for table `db_jonathandj`.`jdj_palavramodulo`
--

DROP TABLE IF EXISTS `jdj_palavramodulo`;
CREATE TABLE `jdj_palavramodulo` (
  `idPalavraModulo` int(10) unsigned NOT NULL auto_increment,
  `idModulo` int(10) unsigned NOT NULL default '0',
  `idPalavra` int(10) unsigned NOT NULL default '0',
  `idRegistro` int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (`idPalavraModulo`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `db_jonathandj`.`jdj_palavramodulo`
--

/*!40000 ALTER TABLE `jdj_palavramodulo` DISABLE KEYS */;
/*!40000 ALTER TABLE `jdj_palavramodulo` ENABLE KEYS */;


--
-- Table structure for table `db_jonathandj`.`noticia`
--

DROP TABLE IF EXISTS `noticia`;
CREATE TABLE `noticia` (
  `idNoticia` int(10) unsigned NOT NULL auto_increment,
  `tituloNoticia` varchar(45) NOT NULL default '',
  `noticia` varchar(500) NOT NULL default '',
  `tags` varchar(100) NOT NULL default '',
  `fonte` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`idNoticia`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `db_jonathandj`.`noticia`
--

/*!40000 ALTER TABLE `noticia` DISABLE KEYS */;
/*!40000 ALTER TABLE `noticia` ENABLE KEYS */;


--
-- Table structure for table `db_jonathandj`.`produto`
--

DROP TABLE IF EXISTS `produto`;
CREATE TABLE `produto` (
  `idProduto` int(10) unsigned NOT NULL auto_increment,
  `tags` varchar(100) NOT NULL default '',
  `nomeProduto` varchar(45) NOT NULL default '',
  `descricao` varchar(500) NOT NULL default '',
  `valor` float NOT NULL default '0',
  PRIMARY KEY  (`idProduto`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `db_jonathandj`.`produto`
--

/*!40000 ALTER TABLE `produto` DISABLE KEYS */;
/*!40000 ALTER TABLE `produto` ENABLE KEYS */;

/*!40101 SET [email="SQL_MODE=@OLD_SQL_MODE"]SQL_MODE=@OLD_SQL_MODE[/email] */;
/*!40014 SET [email="FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS"]FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS[/email] */;
/*!40014 SET [email="UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS"]UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS[/email] */;
/*!40101 SET [email="CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT"]CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT[/email] */;
/*!40101 SET [email="CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS"]CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS[/email] */;
/*!40101 SET [email="COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION"]COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION[/email] */;
/*!40101 SET [email="CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT"]CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT[/email] */;

conexao.asp
<%
Const BD_LOCAL_USER_ID = "root" 'nome de usuário do banco de dados
Const BD_LOCAL_PASSWORD = "root" 'senha do usuário do banco de dados
Const BD_LOCAL_INITIAL_CATALOG = "db_jonathandj" 'nome da base de dados
Const BD_LOCAL_DATA_SOURCE = "localhost" 'nome ou IP do seridor
Const BD_PROVIDER = "{MySQL ODBC 3.51 Driver}"'provider utilizado
dim conexao, stringConexao
stringConexao = "Driver="&BD_PROVIDER&";" & _
"UID=" & BD_LOCAL_USER_ID & ";" & _
"PWD=" & BD_LOCAL_PASSWORD & ";" & _
"Database=" & BD_LOCAL_INITIAL_CATALOG & ";" & _
"Server=" & BD_LOCAL_DATA_SOURCE &";" &_
"Option=35"
set conexao = Server.CreateObject("ADODB.Connection") 
conexao.open stringConexao%>

funcoes.asp
<%
Response.Charset = "utf-8"
'função para fechar objetos criados
sub fechaObj(ByRef obj)
 on error resume next
 if obj.status <>0 then
  obj.close
  set obj = nothing
 end if
 if err.number<>0 then
  set obj = nothing
 end if
end sub

'função para tratar as aspas e possiveis ataques de sql injection
function replaceString(str)
 str	  = str&""
 str	  = replace(str,"  "," ")
 str		 = replace(str,"'","'")
 str		 = replace(str,"""",""") 
 str		 = replace(str,"<","&lt;")
 str		 = replace(str,">","&gt;")
 str		 = replace(str,"\","\\")  
 replaceString = str
end function

function atualizaPalavraTabela(IDMODULO,id,tag)
 'IDMODULO = id da tabela do módulo
 'id	= id do registro do módulo
 'tag   = texto contendo as tags a serem gravadas
 dim palavra, arrayBusca, sql, rs, idPalavra, i
 'verifica se os ids são validos evitando erros
 if IDMODULO <> "" and id <> "" then
  'exclui todos os itens relacionados na tabela palavraModulo referente ao id que estamos trabalhando
  sql = ""&_
	 "DELETE "&_
	 "FROM jdj_palavraModulo "&_
	 "WHERE idRegistro = "&id&" AND idModulo = "&IDMODULO&";" 
  conexao.execute(sql)
  'trata o conjunto de palavras e forma-se um array para tratar um a um
  palavra   = replace(tag,","," ")
  palavra   = replace(palavra,"+"," ")
  arrayBusca  = split(palavra," ")
  'varre o array em busca de palavras existentes
  for i = 0 to uBound(arrayBusca)
   palavra = arrayBusca(i)
   sql = ""&_
	  "SELECT p.idPalavra "&_
	  "FROM jdj_palavra p "&_
	  "WHERE UPPER(p.palavra) = UPPER('"&palavra&"');"
   set rs = conexao.execute(sql)
   if rs.eof then
   'se a palavra não existe na tabela então gravamos
	sql = ""&_
	   "INSERT INTO jdj_palavra ("&_
	   "palavra "&_
	   ")VALUES("&_
	   "LOWER('"&palavra&"'));"
	conexao.execute(sql) 
	'recupera-se o idPalavra do registro que acabou de ser inserido
	sql = ""&_
	   "SELECT LAST_INSERT_ID(idPalavra) AS idPalavra "&_
	   "FROM jdj_palavra "&_
	   "ORDER BY idPalavra DESC "&_
	   "LIMIT 1;" 
	set rs = conexao.execute(sql)	  
   end if
   'armazena-se na variavel o idPalavra
   idPalavra = rs("idPalavra") 
   'gravamos os ids palavra, modulo e registro
   sql = ""&_
	  "INSERT INTO jdj_palavraModulo ("&_
	  "idPalavra, idModulo, idRegistro "&_
	  ")VALUES("&_
	  ""&idPalavra&","&IDMODULO&","&id&");"
   conexao.execute(sql)
  next 
  atualizaPalavraTabela = true
 else
  atualizaPalavraTabela = false
 end if 
end function
%>

busca.asp
[asp]
<%
option explicit
%>
<!--#include file="include/conexao.asp"-->
<!--#include file="include/funcoes.asp"-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR...ransitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Formul&aacute;rio de busca jonathandj</title>
</head>
<%
dim sql, palavra, rs, rsBusca, chave, i, sqlWhere, tabelaHtml, arrayBusca, idModulo, relevancia
chave = replaceString(Request.QueryString("chave"))
%>
<body>
<!--#include file="include/menu.asp"-->
<form action="busca.asp" method="get">
<table>
<tr>
<td><input type="text" name="chave" id="chave" value="<%=chave%>" /><input type="submit" name="submit" value="Procurar" /></td>
</tr>
</table>
</form>
<%
if len(chave)>0 then
'preparamos a busca quebrando as palavras em array
palavra = replace(chave,","," ")
palavra = replace(palavra,"+"," ")
palavra = replace(palavra,"("," ")
palavra = replace(palavra,")"," ")
arrayBusca = split(palavra," ")
'montamos o critério da busca usando a função SOUNEX
for i = 0 to uBound(arrayBusca)
palavra = arrayBusca(i)
if i = 0 then
sqlWhere = " AND ("
else
sqlWhere = sqlWhere & " OR "
end if
sqlWhere = sqlWhere & " SOUNDEX(p.palavra) = SOUNDEX('"&palavra&"') "
next
sqlWhere = sqlWhere & ")"
'executa-se a consulta para pegarmos os dados do módulo
sql = "SELECT DISTINCT m.idModulo, m.modulo, m.titulo, m.pagina, m.id, m.tabela, pm.idRegistro "&_
"FROM jdj_modulo m "&_
"INNER JOIN jdj_palavraModulo pm ON pm.idModulo = m.idModulo "&_
"INNER JOIN jdj_palavra p ON p.idPalavra = pm.idPalavra "&_
"WHERE 1=1 "&sqlWhere&" "&_
"ORDER BY m.modulo;"
set rs = conexao.execute(sql)
if not rs.eof then
idModulo = ""
'percorre cada registro do recorset
do while not rs.eof
'executa nova busca para montar os links do resultado da busca
sql = ""&_
"SELECT m."&rs("titulo")&" AS titulo, m."&rs("id")&" AS id "&_
"FROM "&rs("tabela")&" AS m "&_
"WHERE m."&rs("id")&" = "&rs("idRegistro")&" "&_
"ORDER BY m."&rs("titulo")&";"
set rsBusca = conexao.execute(sql)
if not rsBusca.eof then
'verifica o id do módulo para não duplicar o cabeçalho
if idModulo <> rs("idModulo") or idModulo = "" then
tabelaHtml = tabelaHtml & ""&_
"<table border=""0"" width=""100%"">"&vbNewLine&_
" <tr>"&vbNewLine&_
" <td style=""background-color:#cccccc;"">"&vbNewLine&_
" "&rs("modulo")&""&vbNewLine&_
" </td>"&vbNewLine&_
" </tr>"&vbNewLine
end if
'faz o loop para listar os registros de cada módulo
do while not rsBusca.eof
tabelaHtml = tabelaHtml & ""&_
" <tr>"&vbNewLine&_
" <td>"&vbNewLine&_
" <a href="""&rs("pagina")&rsBusca("id")&""">"&rsBusca("titulo")&"</a>"&vbNewLine&_
" </td>"&vbNewLine&_
" </tr>"&vbNewLine
rsBusca.movenext
'necessário para verificação do próximo cabeçalho a ser criado
idModulo = rs("idModulo")
loop
end if
fechaObj(rsBusca)
rs.movenext
'quando acabou a busca adiciona a tag de fechamento de table
if not rs.eof then
if idModulo <> rs("idModulo") then
tabelaHtml = tabelaHtml & "</table>"&vbNewLine
end if
end if
loop
'fecha a ultima tag table da busca
tabelaHtml = tabelaHtml & "</table>"
'inicia a exibição de palavras relevantes
'**** Obs.: esta parte é opcional, caso deseje não precisa fazer
'faz a mesma consulta realizada no inicio da página
sql = "SELECT DISTINCT p.palavra "&_
"FROM jdj_modulo m "&_
"INNER JOIN jdj_palavraModulo pm ON pm.idModulo = m.idModulo "&_
"INNER JOIN jdj_palavra p ON p.idPalavra = pm.idPalavra "&_
"WHERE 1=1 "&sqlWhere&";"
set rs = conexao.execute(sql)
if not rs.eof then
'se achou alguma palavra com a fonética semelhante então monta o resultado concatenando na variavel
do while not rs.eof
'verifica se a palavra do registro atual já não está na variavel
if inStr(uCase(chave),uCase(rs("palavra")))=0 then
relevancia = relevancia & rs("palavra") &" | "
end if
rs.movenext
loop
'se a variavel tiver algo então adiciona o codigo html a variavel
if relevancia <> "" then
relevancia = "A busca utilizou as seguintes palavras de relev&acirc;ncia para encontrar estes resultados: "&_
"<span style=""color:red;"">"&_
mid(relevancia,1,len(relevancia)-2)&_
"</span>"
tabelaHtml = ""&_
"<table border=""0"" width=""100%"">"&vbNewLine&_
" <tr>"&vbNewLine&_
" <td style=""background-color:#FFCCCC;"" align=""left"">"&vbNewLine&_
" "&relevancia&""&vbNewLine&_
" </td>"&vbNewLine&_
" </tr>"&vbNewLine&_
"</table>"&vbNewLine&_
tabelaHtml
end if
end if
else
tabelaHtml = "<table border=""0"" width=""100%"">"&vbNewLine&_
" <tr>"&vbNewLine&_
" <td style=""background-color:#FFCCCC;"" align=""center"">"&vbNewLine&_
" Nenhum registro encontrado na busca por '<b>"&chave&"</b>'"&vbNewLine&_
" </td>"&vbNewLine&_
" </tr>"&vbNewLine&_
"</table>"&vbNewLine
end if
fechaObj(rs)
'fechamos o objeto de conexão
call fechaObj(conexao)
end if
'imprimimos o resultado da busca e da relevância9quando existir)
Response.Write(tabelaHtml)
%>
</body>
</html>[/asp]
noriciaCadastro.asp
<<A href="mailto:%@LANGUAGE="VBSCRIPT">%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%
option explicit
%>
<!--#include file="include/conexao.asp"-->
<!--#include file="include/funcoes.asp"-->
<%
'numero do ID do Módulo correspondente a tabela
Const ID_MODULO = 1 
dim tituloNoticia, noticia, fonte, tags, sql, rs, idNoticia
'resgata os valores dos inputs
tituloNoticia  = replaceString(Request.Form("tituloNoticia"))
noticia	 = replaceString(Request.Form("noticia"))
fonte	  = replaceString(Request.Form("fonte"))
tags	  = replaceString(Request.Form("tags"))
'verifica se houve o Post do formulário
if Request.ServerVariables("REQUEST_METHOD") = "POST" and len(tituloNoticia)>1 and len(noticia)>1 then
 'executa a gravação do novo registro
 sql = ""&_
	"INSERT INTO noticia ("&_
	"tituloNoticia, noticia, fonte, tags "&_
	")VALUES("&_
	"'"&tituloNoticia&"','"&noticia&"','"&fonte&"','"&tags&"');"
 conexao.execute(sql)
 'recupera o idNoticia que acabou de ser inserido
 sql = ""&_
	"SELECT LAST_INSERT_ID(idNoticia) AS idNoticia "&_
	"FROM noticia "&_
	"ORDER BY idNoticia DESC "&_
	"LIMIT 1;" 
 set rs = conexao.execute(sql)
 idNoticia  = rs("idNoticia")
 fechaObj(rs)
 'chamamos a função que fará o trabalho de criar as palavras de busca
 call atualizaPalavraTabela(ID_MODULO,idNoticia,tags)
 Response.Redirect("noticiaCadastro.asp")
end if
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "[url="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd[/url]">
<html xmlns="[url="http://www.w3.org/1999/xhtml"]http://www.w3.org/1999/xhtml[/url]">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Cadastro de not&iacute;cias jonathandj</title>
</head>

<body>
<!--#include file="include/menu.asp"-->
<form action="noticiaCadastro.asp" method="post">
 <table align="center">
  <tr>
   <td colspan="2" align="center">Cadastro de not&iacute;cia</td>
  </tr>
  <tr>
   <td>T&iacute;tulo: </td>
   <td><input type="text" name="tituloNoticia" id="tituloNoticia" /></td>
  </tr>
  <tr>
   <td>Tags de busca: </td>
   <td><input type="text" name="tags" id="tags" /></td>
  </tr>
  <tr>
   <td>Not&iacute;cia: </td>
   <td><textarea name="noticia" id="noticia" cols="45" rows="6"></textarea></td>
  </tr>
  <tr>
   <td>Fonte: </td>
   <td><input type="text" name="fonte" id="fonte" /></td>
  </tr>
  <tr>
   <td colspan="2" align="center"><input type="submit" name="submit" value="Cadastrar" /></td>
  </tr>
 </table>
</form>
</body>
</html>
<%
fechaObj(conexao)
%>

Quote

- na tabela JDJ_MODULO cadastre os módulos do seu site para que a busca possa interagir, veja o que cada coluna representa abaixo:

|-----------------------------------------------------------------------------------------------------------------------|
|COLUNA |INFORMAÇÃO |
|-----------------------------------------------------------------------------------------------------------------------|
|tabela |Nome da tabela do seu módulo na base de dados |
|id |Nome da coluna que contém a chave primária do seu módulo |
|pagina |Nome da página que exibe as informações completas do seu módulo (veja exemplo que está no banco) |
|titulo |Nome da coluna do módulo que servirá para exibir o texto no link para o visitante do site |
|modulo |Nome amigável a exibir para o visitante do site que irá separar os módulos no resultado da busca |
|-----------------------------------------------------------------------------------------------------------------------|

0

Página 1 de 1


Resposta rápida

  

1 usuário(s) está(ão) lendo este tópico
0 membro(s), 1 visitante(s) e 0 membros anônimo(s)