Esta es una de las cosas que más deseaba hacer cuando comencé a programar y realmente creía que era bien difícil, pero no, es extremadamente fácil y lo puedes hacer en solo minutos.
Introducción:
En nuestro ejemplo, tendremos una tabla en la Base de Datos del tipo MyISAM, ya que este motor soporta Funciones de búsqueda de texto completo (Full-Text). La tabla en si seria en donde guardaríamos las noticias de nuestro sitio web y la búsqueda la vamos a hacer en los campos Titulo y Cuerpo de la Noticia, por lo tanto nos centraremos en ellos solamente.
Además, como es lógico, nos auxiliaremos de un formulario HTML donde introduciremos las consultas enviadas a la Base de Datos. Lo validaremos, para en caso de que no se genere ningún resultado, mostrar un mensaje al usuario y también advertir en caso de que se haya enviado vacío.
Otra de las cosas que debo destacar, es que los resultados de las búsquedas se ordenarán de forma tal, que los primeros serán los que mayor cantidad de coincidencias tengan con la cadena pasada a la consulta.
Bueno, creo que ya es hora de entrar en materia y ver el código, que como bien dice WordPress: Code is Poetry…
La Base de Datos:
Como ya dijimos, nuestra tabla cuenta con un par de campos, título y cuerpo de la noticia, mas el ID claro. Lo que haremos en si es crear un campo FULL-TEXT con los campos en los cuales nos interesa realizar las búsquedas:
CREATE TABLE `noticias` ( `noticia_ID` int(11) NOT NULL auto_increment, `noticiaTitulo` varchar(200) NOT NULL, `noticiaNoticia` text NOT NULL, PRIMARY KEY (`noticia_ID`), FULLTEXT KEY `buscador` (`noticiaTitulo`,`noticiaNoticia`) ) ENGINE=MyISAM;
El formulario HTML:
Todo lo vamos a hacer en una misma página: buscar.php
<h1><a href="<?php echo $_SERVER['PHP_SELF']; ?>">Buscador - By RogerTM</a></h1> <form name="buscar" action="<?php $_SERVER['PHP_SELF'] ?>" method="get"> Buscar: <input type="text" size="50" value="<?php echo $_GET['frase']; ?>" name="frase" /> <input type="submit" name="buscar" value="Buscar" /> </form>
Esto no creo que necesite explicación, solo que el value de la caja de texto es la frase enviada por $_GET[], osea, que se mostrará la frase que buscamos una vez hecha la consulta.
El código PHP:
<?php
// conectar al servidor $server_link = mysql_connect("localhost", "root", "*****");
if(!$server_link){
die("Falló la Conexión ". mysql_error());
}
// seleccionamos la base de datos
$db_selected = mysql_select_db("database", $server_link);
if(!$db_selected){
die("No se pudo seleccionar la Base de Datos ". mysql_error());
}
// varificamos que el formulario halla sido enviado
if(isset($_GET['buscar']) && $_GET['buscar'] == 'Buscar'){
$frase = addslashes($_GET['frase']);
// hacemos la consulta de busqueda
// ver explicación mas abajo
$sqlBuscar = mysql_query("SELECT noticiaTitulo, noticiaNoticia,
MATCH (noticiaTitulo, noticiaNoticia)
AGAINST ('$frase' IN BOOLEAN MODE) AS coincidencias
FROM noticias WHERE MATCH (noticiaTitulo, noticiaNoticia)
AGAINST ('$frase' IN BOOLEAN MODE)
ORDER BY coincidencias DESC", $server_link)
or die(mysql_error());
$totalRows = mysql_num_rows($sqlBuscar);
// Enviamos un mensaje
// indicando la cantidad de resultados ($totalRows)
// para la frase busada ($frase)
if(!empty($totalRows)){
echo stripslashes("<p>Su búsqueda arrojó <strong>$totalRows</strong> resultados para <strong>$frase</strong></p>");
// mostramos los resultados
while($row = mysql_fetch_array($sqlBuscar)){
echo "<strong><a href='#'>$row[noticiaTitulo]</a>:</strong> <em>Coincidencias: ". round($row['coincidencias']) ."</em><br />";
echo "<p>".substr(strip_tags($row['noticiaNoticia']), 0, 255)."...</p>";
}
}
// si se ha enviado vacio el formulario
// mostramos un mensaje del tipo Oops...!
elseif(empty($_GET['frase'])){
echo "Debe introducir una palabra o frase.";
}
// si no hay resultados //
otro mensaje del tipo Oops...!
elseif($totalRows == 0){
echo stripslashes("Su busqueda no arrojo resultados para <strong>$frase</strong>");
}
}
?>
NOTA: Obsérvese el uso de la función strip_tags, en este caso nos sirve para eliminar etiquetas HTML no deseadas y evitar se muestren imágenes u objetos embebidos en el código.
La consulta de búsqueda:
La función MATCH() realiza una búsqueda de lenguaje natural para cadenas contra una colección de textos. Una colección es un conjunto de una o más columnas incluídas en un índice FULLTEXT. La cadena de búsqueda se da como argumento para AGAINST(). Para cada registro en la tabla MATCH() retorna un valor de relevancia, esto es, una medida de similaridad entre la cadena de búsqueda y el texto en el registro en las columnas mencionadas en la lista MATCH().
[...]
Para búsquedas FULL-TEXT en lenguaje natural, se requiere que las columnas nombradas en la función MATCH() sean las mismas columnas incluídas en algún índice FULLTEXT en su tabla. Para la consulta precedente, tenga en cuenta que las columnas nombradas en la función MATCH() (noticiaTitulo y noticiaNoticia) son las mismas que las nombradas en la definición del índice FULLTEXT de la tabla noticias.
[...]
La consulta retorna los valores de relevancia y también ordena los registros en orden decrecente de relevancia. Para conseguir este resultado, debe especificar MATCH() dos veces: una vez en la lista SELECT y otra en la cláusula WHERE. Esto hace que no haya sobrecarga adicional, ya que el optimizador de MySQL se da cuenta que hay dos llamadas MATCH() son idénticas e invoca la búsqueda FULL-TEXT sólo una vez.
Concluyendo:
Como ves ha sido fácil y rápido, solo espero como siempre, que mis ejemplos sirvan a quienes se inician en la programación usando PHP.
Cualquier comentario, duda o sugerencia, no dudes en hacérmelos saber. Yo también aprendo mucho de las opiniones de los lectores que pasan por aquí.
E insisto, no dejes de leer en el Manual de MySQL el capitulo referente a las Funciones de búsqueda de texto completo (Full-Text). Aquí tienes una explicación detallada sobre las búsquedas booleanas, las búsquedas con expansión de consulta, sus limitaciones, como afinarlas y las cosas que quedan aun por hacer en este tipo de consultas.
Nota: Edito el post, pues me faltaba ponerle las funciones addslashes() y stripslashes() en las cadenas de entrada y salida respectivamente.
Interesante chen, ahora vamos a dar un curso facultativo aqui de
Perro Hijo de PutaPHP para los chamacos que van a trabajar con nosotros en lo de los blogs.Ya solucione el problema y el WordPress MU esta pinchando en talla. Era que en el httpd.conf estaba definido el mismo directorio dos veces y en la segunda tenia bloqueado el Rewrite, boberias que pasan.
Quiero poner a esos chamacos a hacer una especie de portal central de los blogs que sea capaz de resumir los feeds de toda la comunidad, poner reseñar los posts mas populares y mas comentados… ponerle un buscador !!!
en fin, toda una pincha gorda, pero bueno, tu sabes como es eso y aqui he visto cosas interesantes porque yo de PHP bueno… se poco, jjeje lo mio es C++, C#, etc, asi que el facultativo tambien va conmigo.
Hola Roger un saludo! yo tambien he creado un buscador con MATCH() AGAINST() y he puesto la funciòn strip_tags (que me romendaron en FW), te pregunto: como es que se podria embeber còdigo en el buscador?; esta funciòn sirve para defenderte un poco de inyecciòn SQL?…
Bueno, me despido estando al pendiente… gracias.
Hola @etzekiel, no entiendo bien lo que quieres hacer, por favor, explícame mejor, si puedes abre un post en FDW y allí vemos mejor lo que quieres, con código y eso
saludos y suerte
Hola Roger, me gustó el sistema pero no lo puedo hacer funcionar, me saltan errores de todo tipo.
Siempre termina en el mismo error:
Parse error: parse error, unexpected T_STRING
En las lineas de conexion, antes de hacer la consulta, etc.. alguna idea?
Hola @Matias, el problema que debes tener es con respecto a las comillas (creo), pues WP las convierte a otros caracteres que no son los que usamos para programar…
No puedes copiar y pegar el código y usarlo así no mas, debes arreglarlo primero, cambiar los caracteres que pone WP por los que se usan en nuestro lenguaje.
Otra cosa debe ser que te saltaste algún punto y coma.
Revisa y si el error persiste, me posteas por aquí.
saludos y suerte
Gracias por contestar Roger, mira, el error lo da en esta línea:
// varificamos que el formulario halla sido enviado
if(isset($_GET['buscar']) && $_GET['buscar'] == ‘Buscar’){
$frase = addslashes($_GET['frase']);
$frase = addslashes($_GET['frase']);
// hacemos la consulta de busqueda
Ya le cambié todas las comillas y lo he revisado varias veces, sigo sin darme cuenta.
El formulario y el resto del código va todo en una misma página no?
Será un problema con la versión de MySQL?
@Matias pues no se… y cerraste la llave ‘{}’??? por otro lado, estas duplicando la linea $frase = addslashes($_GET['frase']);… de todos modos lo sigo mirando a ver que es.
saludos y suerte
Hola me presento, soy [B][I][COLOR="DeepSkyBlue"]ambigus[/COLOR][/I][/B], me declaro novato y quiero decirte antes que nada, excelente aporte. Ahora bien me gustaría saber, acerca de tu aporte: [B]Como hacer un Buscador sencillo, usando PHP y MySQL[/B], puesto que quiero hacer uno para mi web. :-). Entonces me gustaría saber:
[B]1.[/B] ¿Dónde inserto esto?: [CODE]<h1><a href=”<?php echo $_SERVER['PHP_SELF']; ?>”>Buscador – By RogerTM</a></h1>
<form name=”buscar” action=”<?php $_SERVER['PHP_SELF'] ?>” method=”get”>
Buscar: <input type=”text” size=”50″ value=”<?php echo $_GET['frase']; ?>” name=”frase” />
<input type=”submit” name=”buscar” value=”Buscar” />
</form>[/CODE]
[B]a.[/B] En un HTML de la Index.html? (Página de inicio)?
[B]b. [/B]En el archivo buscar.php?
[B]2.[/B] Comprendo que esto forma parte del código buscar.php, pero ¿Cómo lleno las secciones: “localhost”,”root”,”******”?: [PHP]<?php
// conectar al servidor
$server_link = mysql_connect(“localhost”, “root”, “*****”);
if(!$server_link){
die(“Falló la Conexión “. mysql_error());
}
[/PHP]
[B]3.[/B] Actualmente estoy trabajando en el servicio gratuito de [B]gofreeserve.com[/B], me gusta mucho y quiero desarrollar mi web ahi´. Entonces en la base de datos Mysql, tengo una que se denomina [B]gofre_2656604_Prueba[/B], puesto que mis datos son los siguientes:
[COLOR="Orange"][B]
Cuenta gratis de gofreeserve.com:[/B][/COLOR] gofre_2656604
[COLOR="Orange"][B]Contraseña:[/B][/COLOR] *******
En la base de datos he insertado el código de: [CODE]CREATE TABLE `noticias` (
`noticia_ID` int(11) NOT NULL auto_increment,
`noticiaTitulo` varchar(200) NOT NULL,
`noticiaNoticia` text NOT NULL,
PRIMARY KEY (`noticia_ID`),
FULLTEXT KEY `buscador` (`noticiaTitulo`,`noticiaNoticia`)
) ENGINE=MyISAM;[/CODE]
Entonces, ¿Qué debo hacer para que me vaya funcionando?, en tu post planteas una explicación válida, pero debo decirte que no soy muy experto en estos temas, y me gustaría que me enseñarás. :-)
3. Continuando con el archivo buscar.php, dices: [PHP]// seleccionamos la base de datos
$db_selected = mysql_select_db(“database”, $server_link);
if(!$db_selected){
die(“No se pudo seleccionar la Base de Datos “. mysql_error());
}[/PHP]
[B]a.[/B] Acaso debo insertar mi base de datos: [B]gofre_2656604[/B] en donde dice: “database”, y listo?
4. En lo que sigue del código buscar.php, ¿No debo modificar nada más?: [PHP]// varificamos que el formulario halla sido enviado
if(isset($_GET['buscar']) && $_GET['buscar'] == ‘Buscar’){
$frase = addslashes($_GET['frase']);
// hacemos la consulta de busqueda
// ver explicación mas abajo
$sqlBuscar = mysql_query(“SELECT noticiaTitulo, noticiaNoticia,
MATCH (noticiaTitulo, noticiaNoticia)
AGAINST (‘$frase’ IN BOOLEAN MODE) AS coincidencias
FROM noticias
WHERE MATCH (noticiaTitulo, noticiaNoticia)
AGAINST (‘$frase’ IN BOOLEAN MODE)
ORDER BY coincidencias DESC”, $server_link)
or die(mysql_error());
$totalRows = mysql_num_rows($sqlBuscar);
// Enviamos un mensaje
// indicando la cantidad de resultados ($totalRows)
// para la frase busada ($frase)
if(!empty($totalRows)){
echo stripslashes(“<p>Su búsqueda arrojó <strong>$totalRows</strong> resultados para <strong>$frase</strong></p>”);
// mostramos los resultados
while($row = mysql_fetch_array($sqlBuscar)){
echo “<strong><a href=’#'>$row[noticiaTitulo]</a>:</strong> <em>Coincidencias: “. round($row['coincidencias']) .”</em><br />”;
echo “<p>”.substr(strip_tags($row['noticiaNoticia']), 0, 255).”…</p>”;
}
}// si se ha enviado vacio el formulario
// mostramos un mensaje del tipo Oops…!
elseif(empty($_GET['frase'])){
echo “Debe introducir una palabra o frase.”;
}
// si no hay resultados
// otro mensaje del tipo Oops…!
elseif($totalRows == 0){
echo stripslashes(“Su busqueda no arrojo resultados para <strong>$frase</strong>”);
}
}
?>[/PHP]
Ahora bien, me gustaría ir dando paso por paso, podrías porfavor ayudarme en esto? :-)
Espero ansiosamente una respuesta.
esta poca madre no tuve ningun error! gracias fué de gran ayuda esto para mi1!!
Hola,
sabes de que estoy intentando en crear un buscador utilizando una caja de texto y un boton, al momento de presionar el boton me muestre los resultados de la busqueda.
Al obtener un registro te permita seleccionarlo y al hacer esto se coloque la informacion automaticamente en otras cajas de texto que ye he creado, esto con la finalidad de completar informacion de un reporte que estoy realizando.
Le agradezco de antemano si me pudiera auxiliar y aconsejar en como realizar este boton ya que el codigo que usted proporciona no me funciono;
Que tenga un excelente dia y espero pueda contestarme lo antes posible a mi duda, hasta luego.
Bueno algo que puede interesar http://www.thedeadmanspage.org/portafolio
En la seccion programacion hay un script bastane simple, un poco mas que este, espero sirva :)
Amigos a mi no me saltan errores, pero al momento que quiero realizar una busqueda desde mi INDEX, no busca nada y siempre me deja en el index. Si alguien pudiera ayudarme, que pasos debo seguir les estoy muy agradecido de verdad. Saludos a todos
Saludos. por lo que veo MATCH
AGAINST funciona : solo con una tabla de la base de datos???
Necesito simplificar el buscador que estoy realizando, dependiendo de la cantidad de palabras introducidas en el campo de TEXTO divido esta cadena y realizo la sentencia usando LIKE por cada una de las tablas y los campos necesarios. Habra otro metodo mas efectivo?
Hola Roger: Queria hacerte una consulta. Yo implemete un buscador como el ejemplo que tu das en el blog, la limitacion que encuentro en usar Match y AGAINST es la longitud mínima de las palabras a indexar, para lo cual encontré que se puede modificar las variables de sistema aplicando
ft_min_word_len. Mi inquietud es como se modifica esta variable o si conviene mas buscar algun truco para las busquedas de tes letras. Gracias y saludosY para hacer el link hacia mi noticia completa?
ya lo solucioné!
Hola, interesante tutorial, pero como puedo hacer una base de datos y que nombre le coloco?
SAludos =)
Hola, muy buenas, buscando ayuda por internet he llegado a tu blog, y me gustaria hacerte una pregunta, seguramente te parecera una tonteria pero me tiene liado, te explico, estoy haciendo un buscador y mi problema es “conceptual”, se hacer un buscador que me busque en una tabla, por ejemplo para un login de usuario, pero luego pretendi hacer un buscador de noticias, que es lo que me ha traido hasta aquí pero tengo una duda, yo dispongo de un directorio noticias ¿como meto las noticias en la tabla sql?, me refiero con poner un campo identificador y otro nombre de la noticia ¿funcionaria?, me da que no….y por ello me estoy replanteando la intención de hacer una busqueda por directorio, pero aun asi me quedo con la duda de lo expuesto anteriormente y viendo este tutorial y que controlas, pues aprovecho la situación y te pido consejo y ayuda.
Saludo
He me acabas de salvar la vida. Un saludo muy cordial… Muchas, muchas gracias ;D …
hola, muy buen buscador, pero tengo un problema,al presionar enter , en vez del boton , no busca, lei que se puede agregar un javascript , pero tampoco funciona, como puedo arreglarlo?
gracias
HOla, segui los pasos que muestras pero al momento de la busqueda tengo que dar click boton buscar, pero si doy enter no busca. Ojala puedas ayudarme con ese problema
Gracias por el desarrollo. Me solucionaste la vida y me abriste un mundo.
Muy buen buscando, gracias, ahora mi pregunta es como puedo hacer para que busque en 2 Tablas SQL, a la vez.. probe lo siguiente:
FROM noticias, TABLA 2 WHERE MATCH (noticiaTitulo, noticiaNoticia)
Pero la verdad no funciono, en TABLA 2, tengo los MISMO CAMPOS QUE EN LA TABLA NOTICIAS denominados de la misma MANERA, para ver si me arroja los RESULTADO, pero no ocurre NADA.!!
Podrias Ayudarme porfavor, incluso mi meta es hacer que busque en 4 TABLAS Simultaneamente..
SALUDOS Y GRACIAS.!!
AMigo se le agradece el aporte esta muy bueno aprendi mucho, no savi esa utilizadad en php, y me disets una idea para agregarle utilidades a mi sistema d einfromacion gracias,,,,,,,,,,,,si tuvieras estrellitas te dava cinco
Gracias por el aporte me sirvio bastantes, una duda cuando buscas palabras de 3 letras no me arroja nada porque ?
Hola @roberto lopez… Aquí en este link explica cómo solucionar ese problema http://dev.mysql.com/doc/refman/5.0/es/fulltext-fine-tuning.html
Saludos
Hola roger, tengo un problema con lo de las 3 letras o menos, no puedo editar los archivos del servidor, porque estoy en un host gratuito.
Hay alguna otra forma de lograr que el buscador haga consultas de 3 o menos letras???.
¿Si cambio a un host pago se pueden editar los archivos?
Saludos y gracias
La pregunta del millon,
como ago para que me de resultados?
es decir ago lo que dice el tutorial coloco donde esta la base de datos pero y luego como le indexo los resultados que hay es decir
si solo corro el buscar.php ya conectado con la base mysql
todo lo que busque me dice no encontrado no encontrado..
es decir como ago para que me arroje resultados cuack.
Hola , muy bueno el buscador, pero tengo un problema,
como hago para que cuando le de a buscar me traiga los resultados de las palabras, pues me trae lo siguiente
(Su búsqueda arrojó 1 resultados para texto 1
: Coincidencias: 1)
No me aparece la palabra
gracias
Hola a todos hay alguna manera de mostrar los ID o como se pueden hacer los link para que se muestre la información completa
muy buen codigo Roger, tengo una pregunta, espero me puedan dar una mano, necesito que una vez que haga realizado la busqueda, al dar click sobre el titulo me diriga a la web con el contenido del mismo, para eso he aumentado un campo en mi base de datos de nombre web
CREATE TABLE `pagina` (
`id` int(11) NOT NULL auto_increment,
`titulo` varchar(200) NOT NULL,
`contenido` text NOT NULL,
`web` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `buscador` (`titulo`,`contenido`)
) ENGINE=MyISAM;
y dentro del codigo para indicar el resultado he puesto
// mostramos los resultados
$web=$_GET['web'];
while($row = mysql_fetch_array($sqlBuscar)){
echo “$row[titulo]: Coincidencias: “. round($row['coincidencias']) .”“;
echo “”.substr(strip_tags($row['contenido']), 0, 255).”…”;
}
pero no me envia a ningun lado, podrian ayudarme a buscar la forma de como ingresar a la web del titulo de la busqueda, gracias
hola atodos me declaro novato en programacion php….
alguien me puede ayudar a realizar un busqueda con un texto de campo pero siningun boton, que cuando demos la clave del cliente nos aparesca el nombre en un campo de texto….
amigo tengo una duda con este buscador lo que pasa que yo tengo una web de noticias que las voy agregando yo manualmente sin registrarlas en el mysql. es posible que al buscar mediante tags me rebise los archivos .html de cada noticia y la muestre ?