Autor Tema: Busqueda PHP + MYSQL  (Leído 3958 veces)

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Busqueda PHP + MYSQL
« en: 03 de Enero de 2011, 16:52:54 pm »
Mi propósito es crear un buscador que evite buscar palabras con menos de 3 letras (preposiciones, conjunciones...) pero no se me ocurre ninguna manera de hacer ese filtro...
de momento tengo lo siguiente:
<?PHP
$busqueda 
substr($_POST[&#39;q&#39;], 9); //Esto es por que en la busqueda aparece la palabra "BUSQUEDA:"
   //CUENTA EL NUMERO DE PALABRAS 
   
$trozos=explode(" ",$busqueda); 
   
$numero=count($trozos); 
  if (
$numero==1) { //Si solo buscas una palabra...
   
$query mysql_query("SELECT * FROM noticias WHERE titulo LIKE &#39;%".$busqueda."%&#39; OR texto LIKE &#39;%".$busqueda."%&#39;");
   if(
mysql_num_rows($query)){
   while (
$noticia mysql_fetch_array($query)) {
	
 
$comments mysql_query("SELECT * FROM `comments` WHERE para=&#39;".$noticia[&#39;id&#39;]."&#39;");
echo&#39;        <div class="article">
          
<h2><a href="index.php?pag=Ver&ID=&#39;.$noticia[&#39;id&#39;].&#39;">&#39;.$noticia[&#39;titulo&#39;].&#39;</a></span></h2>
          
<class="infopost">Publicado <span class="date">el &#39;.$noticia[&#39;fecha&#39;].&#39;</span> por <a href="#">&#39;.$noticia[&#39;autor&#39;].&#39;</a> | Archivado en <a href="index.php?pag=Categorias&cat=&#39;.$noticia[&#39;categoria&#39;].&#39;">&#39;.$noticia[&#39;categoria&#39;].&#39;</a> <a href="index.php?pag=Ver&ID=&#39;.$noticia[&#39;id&#39;].&#39;#Comentarios" class="com">Comentarios: <span>&#39;.mysql_num_rows($comments).&#39;</span></a></p>
          
<div class="clr"></div>
          <
div class="img"><img src="images/article1.jpg" width="198" height="188" alt="" class="fl" /></div>
          <
div class="post_content">
            <
p>&#39;.$noticia[&#39;texto&#39;].&#39;</p>
          
</div>
          <
div class="clr"></div>
        </
div>&#39;; 
//while
}else{ //num_rows
  
echo "No encontramos ninguna publicaci&oacute;n que concuerde con su busqueda";
}
  } elseif (
$numero>1) { //si buscas más de 1 palabra...
   
$query mysql_query("SELECT *, MATCH (titulo, texto)
AGAINST ( &#39;%"
.$busqueda."%&#39; ) FROM noticias WHERE
MATCH (titulo, texto) AGAINST ( &#39;%"
.$busqueda."%&#39; IN
BOOLEAN MODE ) LIMIT 15"
);
   if(
mysql_num_rows($query)){
   while (
$noticia mysql_fetch_array($query)) {
	
 
$comments mysql_query("SELECT * FROM `comments` WHERE para=&#39;".$noticia[&#39;id&#39;]."&#39;");
echo&#39;        <div class="article">
          
<h2><a href="index.php?pag=Ver&ID=&#39;.$noticia[&#39;id&#39;].&#39;">&#39;.$noticia[&#39;titulo&#39;].&#39;</a></span></h2>
          
<class="infopost">Publicado <span class="date">el &#39;.$noticia[&#39;fecha&#39;].&#39;</span> por <a href="#">&#39;.$noticia[&#39;autor&#39;].&#39;</a> | Archivado en <a href="index.php?pag=Categorias&cat=&#39;.$noticia[&#39;categoria&#39;].&#39;">&#39;.$noticia[&#39;categoria&#39;].&#39;</a> <a href="index.php?pag=Ver&ID=&#39;.$noticia[&#39;id&#39;].&#39;#Comentarios" class="com">Comentarios: <span>&#39;.mysql_num_rows($comments).&#39;</span></a></p>
          
<div class="clr"></div>
          <
div class="img"><img src="images/article1.jpg" width="198" height="188" alt="" class="fl" /></div>
          <
div class="post_content">
            <
p>&#39;.$noticia[&#39;texto&#39;].&#39;</p>
          
</div>
          <
div class="clr"></div>
        </
div>&#39;; 
//while
}else{ //num_rows
  
echo "No encontramos ninguna publicaci&oacute;n que concuerde con su busqueda";
}
  } 
?>
« Última modificación: 14 de Enero de 2011, 22:10:49 pm por judoka »

Comunidad PHPeros

Busqueda PHP + MYSQL
« en: 03 de Enero de 2011, 16:52:54 pm »

Desconectado westwest

  • PHPero Master
  • ******
  • Mensajes: 2.837
  • Karma: 104
  • Sexo: Masculino
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #1 en: 03 de Enero de 2011, 17:06:19 pm »
for($i=0;$i<$numero;$i++) {
if(strlen($trozos[$i]) <= 3) { unset($trozos[$i]); }
}
$busqueda = implode(' ', $trozos);
$numero = substr_count($busqueda, ' ')+1;

Esto deberias ponerlo entre $numero=count($trozos); y if($numero==1) {

Como verás uso un for para recorrer cada palabra del array $trozos eliminando aquellas menores de 3 letras; luego lo uno por espacios y actualizo el numero de palabras en $numero.

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #2 en: 03 de Enero de 2011, 18:18:17 pm »
Muchas gracias por contestar tan rápido. Sigue sin funcionar, al escribir por ejemplo "de", siguen apareciendo resultados.

Desconectado CarlosRdrz

  • Moderador Global
  • PHPero Master
  • *****
  • Mensajes: 2.505
  • Karma: 131
  • Sexo: Masculino
  • A.k.a. TLX
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #3 en: 03 de Enero de 2011, 23:56:57 pm »
Es mejor que crees una pequeña coleccion de palabras de uso común como tu dices, como preposiciones conjunciones y tal y luego compruebes si cada palabra de la busqueda está en esa lista, para eliminarla.

Que sean palabras pequeñas no significa que sean irrelevantes. La propia prueba de ello es buscar PHP en google, o WOW, o cualquier sigla en general.

Además implementarlo es fácil, puedes hacer un array con la lista de palabras...
$filtro = array("de", "con", "para" ...)

Y luego palabra por palabra compruebas con in_array si esta en la lista, y si lo está, la suprimes.

Saludos!
La dedicación de mi respuesta sera directamente proporcional a la dedicación de tu pregunta.
Hacer códigos que entiendan las máquinas es fácil, lo difícil y realmente útil es hacer códigos que entiendan las personas.
http://twitter.com/CarlosRdrz
http://www.carlosrdrz.es

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #4 en: 04 de Enero de 2011, 01:40:09 am »
Tienes toda la razón TLX. Para aprender yo y que no tengáis que darme el código resuelto, me podrías ayudar diciendome con que funciones puedo eliminar y hacer el filtro?
De momento me has dicho que la coleccion la haga con arrays y luego haga un in_array para buscar si están esas palabras en el texto, y luego que? borrar?
Muchas gracias, un saludo!

Desconectado FeDe

  • PHPero Avanzado
  • ****
  • Mensajes: 448
  • Karma: 35
  • Sexo: Masculino
  • BaDyDj -> ¡Mi Stylo, Mi ViDa!
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #5 en: 05 de Enero de 2011, 21:45:25 pm »
Tienes toda la razón TLX. Para aprender yo y que no tengáis que darme el código resuelto, me podrías ayudar diciendome con que funciones puedo eliminar y hacer el filtro?
De momento me has dicho que la coleccion la haga con arrays y luego haga un in_array para buscar si están esas palabras en el texto, y luego que? borrar?
Muchas gracias, un saludo!

Buenas,

Vamos a explicarte brevemente como funcionaría...

Primero obtenemos nuestra cadena de búsqueda y palabras que queremos eliminar...

$cadena "Foros de programacion";
$cens = array("a","de","por","como","hasta");


Después las separaremos creando un array, usando explode...

$exp explode(" ",$cadena);

Esto devolvería: un array con datos: Foros, de, programacion similar a si pusieramos: array("Foros","de","programacion");
Entonces como bien ha dicho TLX deberíamos buscar con in_array la palabra a eliminar ¿como?
Extraemos con foreach cada palabra del array $cens como $palcens & luego definimos si se encuentra en el array ya separado con explode ($exp).
Despues buscamos la posicion de la palabra en nuestro array para definirlo como vacío en la cadena separada.

foreach($cens As $palcens) {
if(
in_array($palcens,$exp)) {
$arraysearch array_search($palcens,$exp);
$exp[$arraysearch] = "";
}
}


& despues solo nos quedaría volver a montar nuestra cadena de búsqueda.
<?php
foreach($exp As $palexp) {
$cadenanueva .= $palexp " ";
}


Y así podríamos tener una función simple & casera! :D
Sin Firma me haces una? :P

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #6 en: 05 de Enero de 2011, 22:56:28 pm »
Uff.. muchisimas gracias, me han entrado ganas de volver a casa de mis vacaciones solo para ponerlo en práctica.
Te puse un + por la explicación, de verdad, muy bien explicado.
Ya os comentaré que tal se me dió, un saludo.

Desconectado FeDe

  • PHPero Avanzado
  • ****
  • Mensajes: 448
  • Karma: 35
  • Sexo: Masculino
  • BaDyDj -> ¡Mi Stylo, Mi ViDa!
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #7 en: 05 de Enero de 2011, 23:02:29 pm »
Gracias a tí !

& espero que te funcione que para eso estamos! jejeje

Un abrazo.
Sin Firma me haces una? :P

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Buscador completo
« Respuesta #8 en: 09 de Enero de 2011, 16:21:11 pm »
Bueno, bueno... ¡¡ maravilloso !!
Me ha servido perfectamente y lo tengo comprendido ;)
Una dudilla, estoy haciendo para que me "destaque" las palabras que he buscado.
En principio, mi idea es con un array para que no distinga entre mayúsculas y minúsculas:

$sub
=array(strtolower($nbusqueda),strtoupper($nbusqueda),ucwords(strtolower($nbusqueda)));

Y luego unos str_replace para que me destaque las palabras:

$texto
=str_replace($sub,&#39;<i><b>&#39;.$nbusqueda.&#39;</b></i>&#39;,&#39;GALERIA&#39;); 
$titulo=str_replace($sub,&#39;<i><b>&#39;.$nbusqueda.&#39;</b></i>&#39;,&#39;Galeria de imagenes&#39;); 

En total quedaría algo así:

$nbusqueda 
"Galeria";
$sub=array(strtolower($nbusqueda),strtoupper($nbusqueda),ucwords(strtolower($nbusqueda)));
$texto=str_replace($sub,&#39;<i><b>&#39;.$nbusqueda.&#39;</b></i>&#39;,&#39;GALERIA&#39;); 
$titulo=str_replace($sub,&#39;<i><b>&#39;.$nbusqueda.&#39;</b></i>&#39;,&#39;Galeria de imagenes&#39;); 
echo $titulo."<br>".$texto

De momento hace su función, pero he topado con el problema de que si la palabra contiene algo antes o después(ya sean paréntesis, exclamaciones, interrogaciones...) no la destaca, ya que busca la palabra suelta.
A ver si me explico:
ESTO SI LO ENCUENTRA Y HACE LO SIGUIENTE:
Galeria de imagenes
ESTO NO LO ENCUENTRA Y CON LO CUAL SE QUEDA IGUAL:
¡¡Galeria de imagenes!!

Había pensado hacer algo así como en las querys con los "%", pero no sé hacerlo por desgracia.
¿Qué me recomiendan para enmendar mi problema?

Desconectado CarlosRdrz

  • Moderador Global
  • PHPero Master
  • *****
  • Mensajes: 2.505
  • Karma: 131
  • Sexo: Masculino
  • A.k.a. TLX
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #9 en: 09 de Enero de 2011, 16:37:19 pm »
Hola de nuevo!

Podrías crear una copia de la cadena a buscar, y en esta copia eliminar todos los "operadores" que se aplican a las palabras, como:
', !, ¡, ?, ¿, "...
Y todos esos caracteres que modifican las palabras.

Otra solución, si solo quieres tener las letras, es hacer eso mismo, comprobar que cada caracter sea una letra entre a y z o A y Z o 0-9 o un espacio en blanco.
Puedes usar expresiones regulares para hacer esto, o bien pasar cada caracter ( $cadena{n} ) y comparar entre los valores ASCII de los limites de arriba.
Para eso se utiliza la funcion ord(), aunque no estoy seguro de si en PHP podrías comparar directamente los caracteres en plan:
'a' < $char && $char < 'z'

EDITO
Hay una función que hace todo por tí, te comprueba si es una letra o un numero, y devuelve TRUE si la cadena pasada es alfanumerica (letras y numeros)
http://www.php.net/manual/en/function.ctype-alnum.php
También podrias usar esta funcion o otra por el estilo para hacer eso mismo

Si necesitas ayuda con cualquiera de las opciones (entendería que con la segunda necesitarías mas ayuda) no dudes en pedirla.
Para mi, la mejor opción, es la segunda, comprobar el valor ASCII.

Saludos!
« Última modificación: 09 de Enero de 2011, 16:39:40 pm por TLX »
La dedicación de mi respuesta sera directamente proporcional a la dedicación de tu pregunta.
Hacer códigos que entiendan las máquinas es fácil, lo difícil y realmente útil es hacer códigos que entiendan las personas.
http://twitter.com/CarlosRdrz
http://www.carlosrdrz.es

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #10 en: 09 de Enero de 2011, 18:05:21 pm »
Hola, gracias por la rapidez y la ingeniosidad de la respuesta.
Creo entender que tu idea se basa en que compruebe en esa cadena los carácteres que son alfanuméricos para poder eliminar los especiales. Corrígeme si me equivoco.
Pero yo planteo esta otra cosa:

Un visitante busca por ejemplo:
o-soto(La web trata sobre el deporte que yo practico, el judo, que es japonés)
Y hay dos entradas: una en la que pone "o-soto-gake" y otra en la que pone "o-soto-gari".

Ya tendría problemas por dos cosas:
1.-Al eliminar los carácteres especiales se elimina por su puesto la barra "-".
2.-Sigo con el problema de que si hay un/os carácter/eres detrás o antes de la palabra clave que estoy buscando, no me la va a marcar (mira el ejemplo que puse en el comentario de arriba)
Por eso preguntaba también si había alguna solución parecida a por ejemplo la de la consulta con LIKE:

LIKE 
&#39;%".$nbusqueda."%&#39;

Esos por cientos (%) tengo entendido que hacen que no importe si hay uno o varios carácteres anteriores o posteriores a $nbusqueda. Corrigeme si me equivoco :)

¡¡Saludos y gracias de nuevo!!

Desconectado CarlosRdrz

  • Moderador Global
  • PHPero Master
  • *****
  • Mensajes: 2.505
  • Karma: 131
  • Sexo: Masculino
  • A.k.a. TLX
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #11 en: 09 de Enero de 2011, 19:35:55 pm »
Supongo que sí, podrias usar LIKE en la consulta SQL, o bien eliminar todos los caracteres inadecuados como te dije antes.
Simplemente si te interesa mantener el caracter - pues lo mantiene y listo, eliminas los demás.
Y si, % hace eso que has escrito si no recuerdo mal.

De todas formas, si tienes la palabra
o-soto
Eliminas el - quedando:
o soto
Y luego separas la cadena con los espacios (como dijo FeDe al principio ¿no?). Te quedan dos palabras a buscar
o, y soto.
Si buscas soto con LIKE y los % como hemos dicho seguramente te aparecerá o-soto-gari y o-soto-gake, así que no creo que haya ningún problema.

Una combinación de las dos sería lo genial.

Saludos!
La dedicación de mi respuesta sera directamente proporcional a la dedicación de tu pregunta.
Hacer códigos que entiendan las máquinas es fácil, lo difícil y realmente útil es hacer códigos que entiendan las personas.
http://twitter.com/CarlosRdrz
http://www.carlosrdrz.es

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #12 en: 09 de Enero de 2011, 19:44:50 pm »
Claro, pero es que el buscador ya lo tengo. Me busca perfectamente con el método de FeDe.
El problema es lo de "resaltar" lo que has buscado.
Quiero hacer como lo que hace google: http://www.google.es/#sclient=psy&hl=es&site=&source=hp&q=hola&aq=f&aqi=&aql=&oq=&gs_rfai=&pbx=1&fp=60f4a62b56d154cb
Ves que todos los "hola" quedan resaltados?

Desconectado Siquillote

  • PHPero Master
  • ******
  • Mensajes: 4.229
  • Karma: 179
  • Sexo: Masculino
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #13 en: 09 de Enero de 2011, 19:56:24 pm »
Claro, pero es que el buscador ya lo tengo. Me busca perfectamente con el método de FeDe.
El problema es lo de "resaltar" lo que has buscado.
Quiero hacer como lo que hace google: http://www.google.es/#sclient=psy&hl=es&site=&source=hp&q=hola&aq=f&aqi=&aql=&oq=&gs_rfai=&pbx=1&fp=60f4a62b56d154cb
Ves que todos los "hola" quedan resaltados?

Cuando estés mostrando los resultados, puedes hacer un str_replace. Por ejemplo, como tu has dicho con el ejemplo "hola". Le añades las etiquetas <b></b> y listo de la siguiente manera:


$busqueda 
"Hola";
//..... Aqui son las consultas
while($mostrar mysql_fetch_object($consulta)){
      
$total str_replace($busqueda,"<b>".$busqueda."</b>",$mostrar[&#39;campo&#39;]);
      
echo $total;
}


Así lo que hace es marcar en negrica la palabra que coincide o coinciden. Porejemplo, si buscas; Judoka, deberá aparecer así: Judoka. Lo que tienes que hacer ahora es implementar ese código al tuyo :P

#Fdo. Physlet

Desconectado judoka

  • PHPero Avanzado
  • ****
  • Mensajes: 255
  • Karma: 4
  • Sexo: Masculino
  • Programando hasta lo mas alto.
    • Ver Perfil
Re:Evitar la búsqueda de palabras de menos de..
« Respuesta #14 en: 09 de Enero de 2011, 20:02:46 pm »
Gracias por la respuesta, pero eso ya lo hacia, el problema es que me falla: http://www.phperos.net/foro/index.php?topic=7158.msg56095#msg56095
Gracias de todos modos :)