Programar un buscador con PHP y MySQL.
Pasos a seguir para la creación de un buscador con PHP y MySQL.
Supongo al lector familiarizado con la programación en php y la administración básica de Mysql.
Como punto de partida, la información a buscar la tenemos que tener almacenada en una tabla de nuestra base de datos. Pongamos como ejemplo una tabla con artículos técnicos que llamaremos ARTICULOS. Esta tabla ARTICULOS tendrá como mínimo dos campos llamados TITULO y DESARROLLO, que almacenarán el título del artículo y su contenido respectivamente.
Los tipos de los campos a buscar deberán ser CHAR, VARCHAR o TEXT con sus variantes.
Ahora diseñaremos una página con un formulario y una caja de texto para escribir la cadena de consulta "busqueda" y llamar al script de búsqueda "buscar.php". Ejemplo:
<FORM METHOD=POST ACTION="buscar.php">
Buscar: <INPUT TYPE="text" NAME="busqueda">
</FORM>
En el fichero buscar.php es donde está el click de la cuestión.
Hay que hacer la consulta que busque las palabras y devuelva como resultado los registros coincidentes. Hasta aquí parece fácil y podríamos resolverlo así:
SELECT * FROM ARTICULOS WHERE DESARROLLO LIKE '%$busqueda%' OR TITULO LIKE '%$busqueda%'
Pues esta consulta nos mostrará todos los artículos que en su titulo o en su contenido aparezca la frase de búsqueda tal y como nosotros la introducimos. Esto es muy limitado ya que un cambio en el orden de las palabras o un artículo de separación dará al traste con nuestra búsqueda no mostrando los resultados deseados.
Si bien podríamos depurar y mejorar la sintaxis de nuestra búsqueda utilizando el operador LIKE las búsquedas resultarían muy lentas y no tendrían el resultado esperado.
La solución mas eficiente es utilizar los índices FULLTEXT específicamente indicados para estos menesteres. Pues bien esto implica ir a nuestra base de datos, y crear un indice FULLTEXT con todos los campos que deseamos incluir en nuestra busqueda, que en nuestro caso son TITULO y DESARROLLO. Para ello basta con el phpmyadmin o bien escribir la instrucción directamente:
ALTER TABLE ARTICULOS ADD FULLTEXT(TITULO, DESARROLLO);
Una vez creado el índice la instrucción SQL para buscar será:
SELECT * FROM ARTICULOS WHERE MATCH(TITULO, DESARROLLO) AGAINST ('$busqueda')
Esta línea utiliza la función MATCH ... AGAINST ... que encuentra el texto buscado, usando consultas en lenguaje natural parecido a como lo hacen los motores de búsqueda. Además, se calcula internamente una puntuación en función de como aparecen los términos buscados dentro de nuestro artículo.
Perfeccionando la búsqueda:
SELECT * , MATCH (TITULO,DESARROLLO) AGAINST ('$busqueda') AS puntuacion FROM ARTICULOS WHERE MATCH (TITULO, DESARROLLO) AGAINST ('$busqueda') ORDER BY puntuacion DESC LIMIT 50
Esta línea devuelve los 50 primeros resultados encontrados ordenados de mas a menos puntuación. El valor de la puntuacion es un número decimal comprendido entre 0 y 1 por cada ocurrencia del patrón de búsqueda, que se irá sumando si ese patrón es encontrado en varias ocasiones. De cualquier forma esta puntuación es un algoritmo interno de la base de datos.
Algunos problemas. Las búsquedas realizadas con MATCH ...AGAINST en ocasiones fallan cuando el término a buscar contiene una sola palabra. Por el contrario son unas búsquedas rapidísimas que producen mejores resultados que otros métodos mas rudimentarios como el LIKE cuando se trata de varias palabras o frases.
La solución que le he dado a ese problema de las búsquedas con MATCH...AGAINST has sido chequear el número de palabras a buscar, utilizando una búsqueda simple con LIKE en el caso de una sola palabra, y el método MATCH...AGAINST en el caso de varias. Ejemplo del fichero buscar.php
<?php
//cadena de conexion
mysql_connect("host","usuario","password");
//DEBO PREPARAR LOS TEXTOS QUE VOY A BUSCAR si la cadena existe
if ($busqueda<>''){
//CUENTA EL NUMERO DE PALABRAS
$trozos=explode(" ",$busqueda);
$numero=count($trozos);
if ($numero==1) {
//SI SOLO HAY UNA PALABRA DE BUSQUEDA SE ESTABLECE UNA INSTRUCION CON LIKE
$cadbusca="SELECT REFERENCIA, TITULO FROM ARTICULOS WHERE VISIBLE =1 AND DESARROLLO LIKE '%$busqueda%' OR TITULO LIKE '%$busqueda%' LIMIT 50";
} elseif ($numero>1) {
//SI HAY UNA FRASE SE UTILIZA EL ALGORTIMO DE BUSQUEDA AVANZADO DE MATCH AGAINST
//busqueda de frases con mas de una palabra y un algoritmo especializado
$cadbusca="SELECT REFERENCIA, TITULO , MATCH ( TITULO, DESARROLLO ) AGAINST ( '$busqueda' ) AS Score FROM ARTICULOS WHERE MATCH ( TITULO, DESARROLLO ) AGAINST ( '$busqueda' ) ORDER BY Score DESC LIMIT 50";
}
$result=mysql("teleformacion", $cadbusca);
While($row=mysql_fetch_object($result))
{
//Mostramos los titulos de los articulos o lo que deseemos...
$referencia=$row->REFERENCIA;
$titulo=$row->TITULO;
echo $referencia." - ".$titulo."<br>";;
}
?>
Enlaces para completar esta información:
http://www.fabio.com.ar/verpost.php?id_noticia=959
http://dev.mysql.com/doc/mysql/en/Fulltext_Search.html
Seguir navegando a partir aquí:
+ 1 manual relacionado
+ 2 categorias relacionadas
+ 4 comentarios (Añadir)
+ 3 comentarios no revisados
| Autoría, licencia y acciones sobre este artículo |
|
|
Manuales relacionados con este artículo
Categorias relacionadas
A través de las categorías de nuestro directorio se pueden encontrar otro tipo de recursos relacionados con este artículo:
+ Entrar en
MySQL+ Entrar en
Scripts en PHP
Comentarios de los visitantes
|
Los comentarios de los visitantes son para ampliar la información del artículo. Cualquiera puede participar.
|
| Se muestran 4 comentarios revisados |
Comentario de Miguel Anguita
30/7/05
La instrucción utilizada es muy rápida pero he encontrado problemas:
SELECT * FROM ARTICULOS WHERE MATCH(TITULO, DESARROLLO) AGAINST ('$busqueda')
Se trata de buscar distintas palabras en varios campos, pero no he logrado que todas las palabras aparezcan en las búsquedas. Solamente aparecen registros que contienen alguna (o bien todas) de las palabras, pero lo útil (o elegible con alguna opción) es que "todas" las palabras estén en todos los registros seleccionados.
¿Tenésis alguna solución para resolver este problema?.
Gracias por vuestra ayuda y adelante con vuestro magnífico portal.
Muguel Anguita.
Comentario de NeoRod
24/10/07
Me parece muy bonito pero solo sirve para bases de datos y no para archivos comunes he aqui les paso el codigo fuente de un buscador dentro de un directorio web.
Minibuscador php de NeoRod
Busca un texto, dentro de archivos de un directorio web, y lista los resultados con algun contenido del archivo.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>by NeoRod</title>
</head>
<body>
<h1>Minibuscador php de NeoRod</h1>
<p>Busca un texto, dentro de archivos de un directorio web, y lista los resultados con algun contenido del archivo. </p>
<form id="form1" name="form1" method="get">
Buscar Texto en pagina<input type="text" name="q"/>
<input type="submit" value="Buscar" />
</form>
<p>
<?php
$dir = "../colegio"; //colocas la carpeta donde va a buscar los temas
$directorio= @opendir($dir);
if(@opendir($dir)==TRUE)
{
$i=0;
while ($archivo = readdir($directorio))
{
if($archivo != '.')
{
if(!is_dir("$dir/$archivo"))
{
$neo[$i]=$archivo;
$i++;}
}
}
closedir($directorio);
if($_GET["q"]!="")
{
for($j=0;$j<count($neo);$j++)
{
$archivo=$neo[$j];
$fp = fopen($archivo,'r');
//leemos el archivo
$texto = fread($fp, filesize($archivo));
if(eregi($_GET["q"],$texto)==1)
{
$lugar=strpos($texto,"<p>");
echo $prueba;
echo "<p><a href=$archivo>$archivo</a><br>";
echo substr($texto, $lugar, 200);
}
}
}
}
else
echo "no puede abrirse el directorio o no existe<br>"
?>
</p>
<p>Atte. NeoRod </p>
</body>
</html>
visitame en la web: http://gloriososancarlos.org
<a href="http://gloriososancarlos.org">http://gloriososancarlos.org</a>
Comentario de despistao
10/1/08
Hola a tod@s
tengo un problema
creo que phpMyAdmin no me reconoce el algoritmo Match Against
Hace un par de años inserté un buscador como éste en una web que tenía y funcionaba perfectamente...
Desde hace un tiempo estoy trabajando en otra web e inserté el buscador pero no me funciona, luego probé en local el buscador de mi web antigua, qué hace tiempo funcionaba perfectamente, y tampoco funciona.
también ejecuté la consulta sql con el match against, pero phpMyAdmin no encuentra ningún registro y hace la consulta bien...
¿a que se puede deber?
gracias por adelantado
Un saludo
Comentario de despistao
11/1/08
Hola de nuevo,
he encontrado la solución al problema:
insertando “IN BOOLEAN MODE” después de la cadena de búsqueda del AGAINST de la cláusula WHERE. De este modo:
“SELECT distinct id_pelicula, titulo, titulo_original, MATCH (titulo, titulo_original)
AGAINST ( ‘%”.$search.”%’ ) AS Criterio FROM peliculas WHERE
MATCH (titulo, titulo_original) AGAINST ( ‘%”.$search.”%’ IN
BOOLEAN MODE ) ORDER BY Criterio DESC LIMIT 50″
Un saludo
| Comentarios sin revisar |
|
Entre los comentarios no revisados puede haber algunos interesantes que se hayan enviado recientemente.
|
Se han encontrado 3 comentarios sin revisar
Ir arriba