Usuario anónimo ¿Quieres tener tu propio blog?
Crear blog gratis en OboLog

Buscador en PHP

viernes, 10 de diciembre del 2004 a las 00:18
guardado en , ,

Bueeeno, aquesta nit toca post tècnic, que ja he aconseguit _quasi_ acabar una de les parts que trobo més interessant del blog: el cercador. Amb el pas del temps la quantitat d'informació enregistrada a la web ha augmentat considerablement, i sense una bona categorització i organització dels continguts, certs missatges corren el perill de caure en l'oblit. En aquest sentit, tenir un arxiu de missatges agrupats per categories o data pot ser molt útil, però perd efectivitat quan parlem de categoríes amb més de 100 missatges. Trobar un post concret es pot convertir en tota una aventura. És aqui on es posa a prova la utilitat d'un cercador eficient.

La majoria de cercadors que he pogut veure a altres llocs web es limiten a fer cerques per paraules a la base de dades, permetent fer la cerca al títol, al contingut de la web, a paraules clau, etc... i utilitzant operadors del tipus "LIKE" per trobar coincidències amb els termes de recerca. Aquest sistema presenta força limitacions, com haver de repetir la cerca per separat per cada paraula, especificar per separat tots els camps de la base de dades on s'ha de mirar, impossibilitat de donar més importància a unes paraules que d'altres, filtrar paraules de poca rellevància... És aqui on vaig descobrir la utilitat d'un tipus d'index que utilitza MySQL, anomenat "FULL TEXT". La troballa de l'any, certament. El "FULL TEXT" ens permet agrupar diversos camps en un sol índex, per poder realitzar-hi cerques conjuntes mitjançant una sola cadena de caràcters (una paraula o frase), i afegir-hi modificadors a l'estil Google. És a dir, podem utilitzar modificadors com les cometes, per agrupar paraules, els simbols < i > per especificar una major o menos rellevància de certa paraula, els simbols - o + per mostrar només resultats que contingin o no una paraula determinada... I tot això de manera automàtica, amb una consulta senzilla.

Un exemple ens ho farà més fàcil d'entendre: Imagineu que vull buscar un manual de photoshop a la web. La consulta que realitzaria a la base de dades, on prèviament he creat un índex FULL TEXT per a certs camps que m'interessen seria

SELECT * FROM posts WHERE MATCH(titulo,descripcion,contenido,contenido_ext,tipo) AGAINST ('manual de photoshop')

Llestos, així de senzill. Les cerques de FULL TEXT ens permeten, a més, conèixer la rellevància (el camp score) de les coincidències per a cada registre trobat. Així podem tambè ordenar els resultats segons s'acostin més o menys al que buscàvem. Això ho fariem de la següent manera.

SELECT *,MATCH(titulo,descripcion,contenido,contenido_ext,tipo) AGAINST ('manual de photoshop') as score FROM posts WHERE MATCH(titulo,descripcion,contenido,contenido_ext,tipo) AGAINST ('manual de photoshop') ORDER BY score desc;

Només amb això ja disposariem d'una eina força potent per trobar informació a una base de dades (els índex FULL TEXT permeten cerques molt més complexes que aquestes, això us ho deixo investigar a les pròpies especificacions de la página de MySQL). Ens trobem, però, que tan sols un llistat amb el títol dels missatges en què hem trobat continguts interessants pot no ser útil, si la cerca no és suficientment acurada, i tots sabem per experiència que afinar amb les paraules correctes no és tasca senzilla. És aqui on em vaig plantejar de implantar un sistema d'extracció de texte rellevant per la pàgina de resultats del cercador. De nou el sistema de Google que ens mostra la part de la pàgina on apareixen les paraules que estem buscant, em va semblar la millor opció. D'un sol cop d'ull pots veure si aquell missatge on apareixen els termes que busques parla realment del que volíes, ja que no necessàriament ha de ser sempre així.

El que faig es separar cada una de les paraules, eliminar les paraules massa curtes, i veure a quina posició dins del contingut del missatge es troben la resta. Després ordeno aquestes posicions i busco aquella part del texte on aquest termes es troben més aprop entre ells, per mostrar-la a mode d'extracte. Aquest seria l'exemple en PHP, que és el llenguatge en què s'ha programat obokaman.com

$busca_ace = array ("á","é","í","ó","ú","Á","É","Í","Ó","Ú","à","è","ì","ò","ù","À","È","Ì","Ò","Ù","+","<",">");
$reemplaza_ace = array ("a","e","i","o","u","A","E","I","O","U","a","e","i","o","u","A","E","I","O","U"," "," "," ");

$buscar=trim(strtolower($texto));
$buscar=str_replace($busca_ace, $reemplaza_ace, $buscar);

$texto_tmp=explode(" ",$buscar);
foreach ($texto_tmp as $valor) {

if (strlen($valor)>3) {
$texto_tmp2[]=$valor;
}else{
$texto_tmp3[]=$valor;
}

}
if (is_array($texto_tmp2)) {
$texto_incluido=implode(",",$texto_tmp2);
}
if (is_array($texto_tmp3)) {
$texto_omitido=implode(",",$texto_tmp3);
}

Ara tenim les paraules que ens interessen (les més llargues de 3 caràcters) a un array anomenat $texto_tmp2. Només caldrà recòrrer aquest array a cada missatge per cercar les coincidències, mirar la seva posició, i destacar cada paraula al texte resultant.

$text1=html_entity_decode($mensaje);
$text1=str_replace($busca_ace, $reemplaza_ace, $text1);
$text1=preg_replace('/[\n\r\t]/',' ',$text1);
if (is_array($texto_tmp2)) {//4
$posiciones= array();
foreach ($texto_tmp2 as $valor) {
$string=strtolower($text1);
$searched=strtolower($valor);
$offsets= array();
$next=0;

while(1){
$entry = strpos(
$string,
$searched,
$next+$offsets[sizeof($offsets)-1] /*juggling*/
);
if(gettype($entry)==boolean){break;};
$next=strlen($searched);
$offsets[]=$entry;
}

$posiciones=array_merge($posiciones,$offsets);
}
sort($posiciones);
for ($i=0;$i
$n=1;
while ($posiciones[($i+$n)]&&($posiciones[($i+$n)]-$posiciones[$i])<500) {
if ($n>$max) {
$max=$n;
$posicion_def=$posiciones[$i];
}
$n++;
}
}
if ($posicion_def) {
$posicion1=$posicion_def;
}else{
$posicion1=$posiciones[0];
}
if ($posicion1>60) {
$posicion1=$posicion1-60;
}else{
$posicion1=0;
}
unset($posicion_def);
unset($posiciones);
unset($offsets);
unset($max);
}
$text1 = substr(trim($text1),$posicion1,500);
if ($text1!="") {
$text1 = '[...]'.$text1.'[...]';
}
foreach ($texto_tmp2 as $valor) {
$text1 = eregi_replace("($valor)","\\1",$text1);
}

$mensaje és la variable que conté tot el text de cada post. Primer busquem les posicions de les coincidències. Després busquem la posició més alta en què les paraules es trobin més properes entre elles (al menys de 500 caràcters entre cadascuna), i finalment, utilitzem aquesta posició per fer un extracte de 500 caràcters d'aquesta porció del text, destacant cada paraula amb un . Això, a mode d'esboç, és el que fa el cercador d'obokaman per cercar i mostrar els resultats. És el millor de fer les coses a mà: que fan exactament el què tu vols. Estaré encantat de sentir les teves suggerències, crítiques, consells per millorar aquest sistema. Encara no l'has provat?

Mensajes relacionados

Deja tu comentario

Deja tu comentario
Necesitas tener javascript activado para poder dejar comentarios

Identifícate en OboLog, o crea tu blog gratis si aún no estás registrado.

De esta forma, además, podrás mostrar tu imagen en los comentarios y no tendrás que rellenar tus datos cada vez.

Sobre esta anotación

Albert Garcia

Albert Garcia escribió esta anotación hace 4 años. En ella habla sobre Buscadores, Desarrollo Web y Php.

Aún no hay ningún comentario.

Tu podrías dejar el primero.

Login

Comentarios

Descripción y fuentes del upload PHP + AJAX con barra de progreso (lampi)
okis me parece interente pero no consigo que funciona  localmente mis recursos son: windows  xp ......(04 jul)
Una de gallegos (pedro)
Los gallegos son la gente mas imbecil que he tenido la desgracia de conocer...son completamente ......(26 jun)
Descripción y fuentes del upload PHP + AJAX con barra de progreso (Anónimo)
no anda para ningun lado...(18 jun)
Disco duro para tu ps2 (juan javier ramirez )
hola he tenido problemas con mi plystation 2  no agarra todos los videojuegos y tiene un hueco en ......(11 jun)
Disco duro para tu ps2 (kmcf95)
Quiero un disco duro!!!! pero mis preguntas son estas: *A un disco duro externo para ps2 se le  ......(10 jun)

Más comentados

Esa bonita canción entre anuncio y anuncio (172)
Se llaman Múm y la canción se titula Green Grass of Tunnel. ¿Os suena? Me sorprendió de igual ...
Disco duro para tu ps2 (168)
Conectar un disco duro a tu Playstation 2, hacer copias de seguridad de tus juegos a ese disco ...
Descripción y fuentes del upload PHP + AJAX con barra de progreso (129)
Días atrás comenté que había estado trabajando en un pequeño experimento para conseguir implementar ...
Català - Valencià (51)
Siguis o no català o valencià , de ben segur estaràs al dia de la discusió que ha tingut ...
Que tinguem sort (26)
Esta canción es preciosa. Me gustaría poder estar en su piel y ser suficientemente fuerte como para ...

Suscripción

Suscríbete al Feed RSS XML

También puedes suscribirte directamente con alguno de los siguientes enlaces:

  • Suscríbete en Bloglines
  • Suscríbete en Google