Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] PHP OO Errores En Consulta Para Busquedas

Estas en el tema de Errores En Consulta Para Busquedas en el foro de PHP en Foros del Web. Buenas a todos, Llevo mucho tiempo usando este script para consultar búsquedas en el buscador de una de mis webs, el problema es que los ...
  #1 (permalink)  
Antiguo 22/07/2015, 20:05
 
Fecha de Ingreso: noviembre-2008
Ubicación: Cochabamba Bolivia
Mensajes: 519
Antigüedad: 15 años, 5 meses
Puntos: 26
Errores En Consulta Para Busquedas

Buenas a todos,

Llevo mucho tiempo usando este script para consultar búsquedas en el buscador de una de mis webs, el problema es que los resultados no son buenos, pues cuando se realizan búsquedas con palabras que contengan solo 3 letras o menos esto no va bien, por lo cual he tenido que hacer modificaciones en el codigo para ver si la busqueda contiene 3 palabras y en caso sea asi la consulta sea distinta, la verdad hacer muchas revisiones a las frases buscar hace que el codigo sea mas complejo.

Para mejor, uso este codigo para hacer las busquedas en la base de datos:

Código PHP:
Ver original
  1. function ResultMp3s($frase, $ini=0, $max){
  2.     $frase = mysql_real_escape_string($frase);
  3.     $trozos= explode(" ",$frase);
  4.     $numero= count($trozos);
  5.     if($numero==1){
  6.         $cadbusca= mysql_query("SELECT id, genero, artista, titulo FROM music_local WHERE titulo LIKE '$frase' OR artista LIKE '$frase' ORDER BY id DESC LIMIT $ini,$max");
  7.         if(mysql_num_rows($cadbusca)>0){
  8.             while($mp = mysql_fetch_assoc($cadbusca)){
  9.                 $artista = ucwords(str_replace("_"," ",str_replace("-"," ",limp($pl[artista]))));
  10.                 $artistaurl = str_replace("_","-",str_replace(" ","-",limp($pl[artista])));
  11.                 $url = "http://music-strike.net/".$pl[genero_url]."/".$artistaurl."/";
  12.    
  13.                 $img = "http://biografias.music-strike.net/img_bio.php?q=".$pl[artista];
  14.                 $title = limp($mp[titulo])." - ".limp($mp[artista]);
  15.                 $id = $mp[id];
  16.                 $url = "http://mp3.music-strike.net/00".$mp[id]."/".str_replace(' ','+',str_replace('-','+',$mp[artista]))."+-+".str_replace(' ','+',str_replace('-','+',$mp[titulo]))."/";
  17.    
  18.                 $mp3[] = array(
  19.                     genero => $mp[genero],
  20.                     title => $mp[titulo],
  21.                     artista => $mp[artista],
  22.                     titulo => $title,
  23.                     id => $id,
  24.                     url => $url,
  25.                     img => "http://music-strike.net/images/icons/speaker_2.png",
  26.                     coincidencias => "1",
  27.                     );
  28.             }
  29.         }else{
  30.             $cadbusca= mysql_query("SELECT id, genero, artista, titulo FROM music_local WHERE (titulo LIKE '%$frase%' OR artista LIKE '%$frase%') OR (titulo LIKE '% $frase %' OR artista LIKE '% $frase %') ORDER BY id DESC LIMIT $ini,$max");
  31.             while($mp = mysql_fetch_assoc($cadbusca)){
  32.                 $artista = ucwords(str_replace("_"," ",str_replace("-"," ",limp($pl[artista]))));
  33.                 $artistaurl = str_replace("_","-",str_replace(" ","-",limp($pl[artista])));
  34.                 $url = "http://music-strike.net/".$pl[genero_url]."/".$artistaurl."/";
  35.    
  36.                 $img = "http://biografias.music-strike.net/img_bio.php?q=".$pl[artista];
  37.                 $title = limp($mp[titulo])." - ".limp($mp[artista]);
  38.                 $id = $mp[id];
  39.                 $url = "http://mp3.music-strike.net/00".$mp[id]."/".str_replace(' ','+',str_replace('-','+',$mp[artista]))."+-+".str_replace(' ','+',str_replace('-','+',$mp[titulo]))."/";
  40.    
  41.                 $mp3[] = array(
  42.                     genero => $mp[genero],
  43.                     title => $mp[titulo],
  44.                     artista => $mp[artista],
  45.                     titulo => $title,
  46.                     id => $id,
  47.                     url => $url,
  48.                     img => "http://music-strike.net/images/icons/speaker_2.png",
  49.                     coincidencias => "1",
  50.                     );
  51.             }
  52.         }
  53.         $repons = $mp3;
  54.     }else{
  55.         $where = "";
  56.         $peque = FALSE;
  57.         foreach($trozos as $t){
  58.             if(strlen($t)<=3){
  59.                 $peque = TRUE;
  60.                 $agregar[] = $t;
  61.             }
  62.         }
  63.         if($peque==TRUE){
  64.             if(count($agregar)==$numero){
  65.                 foreach($agregar as $ag){
  66.                     $veces++;
  67.                     if($veces==1){
  68.                         $where .= "(artista LIKE '%$ag %' OR titulo LIKE '%$ag %')";
  69.                     }else{
  70.                         $where .= " AND (artista LIKE '% $ag %' OR titulo LIKE '% $ag %')";
  71.                     }
  72.                 }
  73.                 $sqlBuscar = mysql_query("SELECT id, genero, artista, titulo FROM music_local WHERE ".$where." ORDER BY id DESC LIMIT $ini,$max");
  74.             }else{
  75.                 foreach($agregar as $ag){
  76.                     $veces++;
  77.                     if($veces==1){
  78.                         $where .= "AND ((artista LIKE '% $ag %' OR titulo LIKE '% $ag %')";
  79.                     }else{
  80.                         $where .= " OR (artista LIKE '% $ag %' OR titulo LIKE '% $ag %')"; 
  81.                     }
  82.                 }
  83.                 $where .= ")";
  84.                
  85.                 $sql = "SELECT id, genero, artista, titulo,
  86.                 MATCH (artista, titulo)
  87.                 AGAINST ('$frase' IN BOOLEAN MODE) AS c
  88.                 FROM music_local
  89.                 WHERE MATCH (artista, titulo)
  90.                 AGAINST ('$frase' IN BOOLEAN MODE)
  91.                  ".$where." ORDER BY c DESC LIMIT $ini, $max";
  92.                 $sqlBuscar = mysql_query($sql);
  93.             }
  94.         }else{
  95.             $sql = "SELECT id, genero, artista, titulo,
  96.                 MATCH (artista, titulo)
  97.                 AGAINST ('$frase' IN BOOLEAN MODE) AS c
  98.                 FROM music_local
  99.                 WHERE MATCH (artista, titulo)
  100.                 AGAINST ('$frase' IN BOOLEAN MODE)
  101.                 ORDER BY c DESC LIMIT $ini, $max";
  102.             $sqlBuscar = mysql_query($sql);
  103.         }
  104.         // Para los resultados
  105.         while($mp = mysql_fetch_assoc($sqlBuscar)){
  106.             $title = limp($mp[titulo])." - ".limp($mp[artista]);
  107.             $id = $mp[id];
  108.             $url = "http://mp3.music-strike.net/00".$mp[id]."/".str_replace(' ','+',str_replace('-','+',$mp[artista]))."+-+".str_replace(' ','+',str_replace('-','+',$mp[titulo]))."/";
  109.             $mp3[] = array(
  110.                 genero => $mp[genero],
  111.                 title => $mp[titulo],
  112.                 artista => $mp[artista],
  113.                 titulo => $title,
  114.                 id => $id,
  115.                 url => $url,
  116.                 img => "http://music-strike.net/images/icons/speaker_2.png",
  117.                 coincidencias => round($mp[c])
  118.                 );
  119.         }
  120.         $repons = $mp3;
  121.     }
  122.     return $repons;
  123. }

Como pueden ver en esta funcion lo que hago es primero ver si la cadena a buscar es una sola palabra o una frase con varias palabras, en cualquiera de los 2 casos tambien hago una revision si en la cadena a buscar existe alguna palabra con solo 3 palabras o menos, para asi hacer una consulta dependiendo cual sea el resultado.

El problema de esto es qeu algunas consultas no va, dejo algunos ejemplos:

search.music-strike.net/all/man+down/1/
search.music-strike.net/all/la+hormiguita/1/

En el primer ejemplo no sale ningun resultado, cuando en realidad existen datos con esa frase "man Down" en el segundo tampoco sale nada, pero si realizo la busqueda simplemente con "hormiguita" si sale.

Estuve viendo por ahi que esto se podria solucionar haciendo una modificacion en la configuracion de PHP, donde tendria que reducir a 1 el limite de letras dentro de una consulta a MYSQL o algo asi.

O bien si podrian darme alguna alternativa para poder conseguir busquedas mas concretas y relevantes estaria muy agradecido.

Creo que este metodo que uso es muy estandar, ya que si te pones a informarte en todos lados es el mismo metodo que usan para hacer buscadores en PHP, sin embargo no puedo aceptar que grandes buscadores como YouTube, Last.FM, u otros miles que hay usen este metodo, por que sus resultados son muy buenos, digo yo que habra alguna manera mas compleja o profesional de hacerlo, el cual lo desconozco.

Sient haber escrito la biblia aqui, pero creo que era necesario para que puedan entenderme.

Saludos.
  #2 (permalink)  
Antiguo 23/07/2015, 09:42
 
Fecha de Ingreso: noviembre-2008
Ubicación: Cochabamba Bolivia
Mensajes: 519
Antigüedad: 15 años, 5 meses
Puntos: 26
Respuesta: Errores En Consulta Para Busquedas

Mmm. no se, creo que soy muy malo explicando mi problema, no es la primera vez que cuando publico una pregunta pasan de contestar cuando contestan de los demas, si tienen alguna duda algo me gustaria saberlo por favor.

El problema es sencillo, ese script me da problemas, no dan resultados relevantes, ha veces nisiquiera da resultados cuando si existen.

¿Alguien puede decirme algo?

Saludos.
  #3 (permalink)  
Antiguo 23/07/2015, 09:52
Avatar de RollerSky  
Fecha de Ingreso: marzo-2008
Mensajes: 123
Antigüedad: 16 años
Puntos: 8
Respuesta: Errores En Consulta Para Busquedas

Hola fido-strike,

Sin duda la mejor manera para realizar búsquedas es usando el MATCH AGAINST, pues este método de búsqueda excluye palabras que tengan menos de 3 caracteres, pero porqué así? por el simple hecho que el Motor trata de generalizar que las Palabras con menos de 3 caracteres son considerados como "palabras in valor agregado", entre ellas contamos con las preposiciones, a, por, co, de, etc. Si en una cadena de texto dejáramos que se puedan buscar palabras como "de" o "por" sería innumerable la cantidad de registros, esto lo puedes ver en Google, que para el es indiferente escribir "Hoteles de Playa" que "hoteles Playa".

Además este tipo de búsquedas es muy poderoso pues va poniendo un valor porcentual o puntaje a cada ocurrencia de una palabra, por ello si una palabra solo se muestra una vez, para el buscador es prácticamente irrelevante a una palabra que se encuentra tal vez 3 o 4 veces, esto explica que si usas el MATCH AGAINST en tablas con pocos registros( 3 o 4) el resultado no es el mejor, pues está hecho para tablas con cantidades "grandes" de información.

teniendo en consideración esto te recomiendo:

1. Valida que tus tablas tengan bastantes datos, no uno o dos registros.
2. valida mediante alguna condición que si la palabra que deseas buscar es de 3 o menos caracteres, entonces no usas el MATCH AGAINST , sino que usas la sentencia LIKE, que para estos casos es muy "buena".
3. recuerda que para que el MATCH AGAINST surta efecto, este solo sirve para campos de la tabla que deben ser indices de tipo FULLTEXT, y sólo sirve en tablas que no son InnoDB

Teniendo en cuenta esto creo que debes revisar tu código, no se que tanto hace, pero me atrevo a decir que un buscador así no te tomaría mas de 10 lineas de código..

Saludos.
__________________
www.sawedsa.com

Última edición por RollerSky; 23/07/2015 a las 09:55 Razón: Error en el MATCH
  #4 (permalink)  
Antiguo 25/07/2015, 06:20
 
Fecha de Ingreso: noviembre-2008
Ubicación: Cochabamba Bolivia
Mensajes: 519
Antigüedad: 15 años, 5 meses
Puntos: 26
Respuesta: Errores En Consulta Para Busquedas

Gracias por tu respuesta RollerSky, he realizado todas las revisiones, he programado de nuevo por si no encontraba el error, pero al final despues de tanta cabezada di con el problema, al menos alguna solucion alternativa.

El problema no era con Match Agains, sino con el cotejamiento Charset (sensibilidad en mayusculas y minusculas en tablas) en la base de datos.

Por si alguien tiene el mismo problema pienso que siempre es bueno decir la solucion:

Si las tablas estan en UTF o latin... lo recomendable es que sean en ci por ejemplo utf8_general_ci

CI: caso insencible

Así las consultas sean con mayúsculas o no se harán comparaciones con todas aquellas que hayan en la BD.

Saludos.

Etiquetas: busquedas, errores, mysql, select, sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:28.