Busquedas SQL palabras no obligatorias

n1x3r

Buenos días.
Nuevamente vuelvo a pedir consejo de como realizar algo con SQL.
El problema que se me presenta es el siguiente, la gente cuando busca pone lo siguiente:

"Una moto de color rosa claro"

las palabras cortas ya las controlo y son filtradas por lo que se quedaría:

"moto color rosa claro"

El problema esta cuando el string donde se busca las palabras es:

"Moto modelo XX de color rosa"

Si lo hacemos por ejemplo con un like no saldrá ningún resultado pues la palabra "claro" no la va a encontrar.

Este es mi gran problema que seguro que tiene una pequeña solución.
Lo ideal es que la búsqueda se realice como hace google en búsqueda avanzada que pone "cualquiera de estas palabras" en la que se muestre el resultado inclusive si alguna falta.
He pensado en hacerlo con OR pero el problema creo que si buscamos:

"Una moto de color rosa claro"

Nos saldrá todas las motos sean del color que sea, o coches del mismo color o.. etc.

¿Alguna idea?

Gracias!! :)

eXtreM3

Por separado no puedes hacer porque te saldrían todos los resultados para cada palabra y obviamente no es lo que quieres.

Mmm no sé cómo lo tendrás estructurado, pero las veces que he tenido que hacer una búsqueda así, lo hacía por campos, me explico. En tu caso, deberías tener una tabla que fuera "datos_vehiculo" con campos tal que: id, tipo (moto / coche), color... de manera que en tu consulta puedes parametrizar en el where todo lo que quieras con un LIKE

tipo like moto (abarca moto de montaña, moto de carretera...)
color like rosa (por si guardas algún color en plan rosa metalizado)

Me has entendido?

1 respuesta
n1x3r

#2 Si, pero no está estructurado así, trabajo sobre una plataforma antigua y digamos que es un texto plano el campo en donde se busca y no está parametrizado nada :S

Lo ideal es que la búsqueda si no encuentra nada con un like normal que pueda pasar de algunas palabras para poder obtener un resultado, si no es el exacto que sea lo mas acertado posible.

El problema esta en esa palabra "gazapo" (que le digo yo, que puede estar en cualquier parte de la frase, como por ejemplo "amoto") esa palabra que o bien no existe o que el usuario escribe mal y jamas va a encontrar nada.

En algunos casos tengo creado un hook que si ve la palabra "amoto" la cambia por "moto" o cambiar de plural a singular, etc etc. Pero me es imposible controlarlo todo de esa forma, sólo puedo controlar algunas palabras.

JuAn4k4

Yo tiraría de http://lucene.apache.org/solr/ o algo similar.

Básicamente es una app web en java en la que indexas documentos y luego realizas búsquedas.

No he probado otros, tienes http://www.elasticsearch.org/ y en su día yo mire unos cuantos más y me decante por solr que encajaba bastante bien.

Solr:

Puedes controlar el hecho de que escriba mal las palabras (No haciendo transformaciones prematuras, sino mirando palabras similares al o que escribes que tengan más resultados).

Puedes realizar busquedas facetadas.

Puedes realizar near-realtime-search.

Puedes ponerlo en alta disponibilidad.

Puedes hacer muchas otras cosas

O eso, o establecer etiquetas a tus "assets" y buscar las keywords del usuario entre las etiquetas.

1 respuesta
n1x3r

#4 Lo que me comentas supongo que trabajará con algo parecido a SOUNDEX, pero esto tampoco solucionaría mi problema. Con las palabras clave si me has dado una buena idea, le daré vueltas.

De mientras sigo buscando alguna solución alternativa.

bLero

#1

Supongamos:

  • Búsqueda del usuario: moto de color azul
  • Posible resultado: moto azulada modelo XX 2010

algoritmo de búsqueda:

1 - Stemming
2 - Combinaciones de 2 palabras
3 - Pagerank
4 - Extensión de resultados
5 - Pagerank y resultados finales

A partir de este punto se pueden hacer muchas más cosas para refinar los resultados, si alguien está interesado que comente.

1 1 respuesta
n1x3r

Y como controlas las palabras gazapo? Dime con cual de tus algoritmos sacas resultado si el usuario busca... "Moto azul barata" y "barata" no se contempla en ningún sitio. Piensa q tampoco la podemos controlar, imagina q en vez de "barata" el usuario pone "to wapa" o "reshulona" lo ideal es poder ignorar las palabras que te impiden dar un resultado. De todo lo demás que comentas tomo nota.

1 respuesta
MisKo

Estoy desde el móvil, luego en casa si puedo te lo amplio.

Lo que necesitas es una búsqueda piramidal donde órdenes lo que encuentres según importancia y hasta un numero Xavier de resultados.

Es decir, en tu caso, buscaría primero con las cuatro palabras, después con todas las combinaciones posibles de tres palabras que puede generar tu búsqueda respetando el orden, después lo mismo con dos, etc...

Estoy habría que limitarlo en función de lo que te interese mostrar, si pones cuatro términos en la búsqueda, y al final solo ves resultados con dos, los resultados que muestres no se van a parecer mucho a lo que busca el usuario, pero al menos habrá resultado.

Si te esperas 40 mins que llego a casa, te pongo un ejemplo con tu cadena de búsqueda.

Un saludo

1 respuesta
bLero

#7 Las busquedas son con combinaciones de 2 palabras.

Si buscas "Moto azul barata" y "barata" no se encuentra en ningún sitio al final encontrarás los resultados de: moto y azul porque las búsquedas serán la union de 3 búsqueda independientes:

"moto" + "barata"
"moto" + "azul"
"azul" + "barata"

Además al utilizar pagerank puedes utilizar (descubrir) otras palabras importantes y relevantes con las que hacer una nueva búsqueda para ampliar resultados. Por ejemplo, si buscas:

Moto azul barata, y hay muchos resultados de "moto" + "azul" que además incorporen la palabra "económica", entonces esa palabra tendrá buena puntuación y podrás refinar la búsqueda volviendo a hacer una query con las palabras importantes descubiertas.

#8

Ese es el algoritmo clásico (simplificado) de búsqueda de los años 90-95, el problema es que además de ser bastante ineficiente, no es inteligente, nunca obtendrás resultados que se salgan de las palabras por las que buscas, y la relevancia irá en función del nºpalabras query / nºpalabras resultado en vez de el significado semántico real del resultado.

No obstante, para algo como lo que quiere #1 es más que de sobra.

1 respuesta
MisKo

#9 No es lo más optimo, pero para serte sincero, no hago ese tipo de búsquedas y no se me ha ocurrido otra cosa xD, ademas tiene el inconveniente de que puede acabar mostrando resultados que poco tienen que ver con lo que busca el usuario si se eliminan muchas palabras.

Otra forma de hacer lo que yo digo, desconozco si mas o menos optimizado ( se me ha ocurrido ahora por la mañana, no he usado esto nunca ), sería con expresiones regulares:

http://dev.mysql.com/doc/refman/5.5/en/regexp.html

NeV3rKilL

La gracia está en los grafos que te va a ponderar los resultados más importantes. Puedes hacerlos más o menos restrictivos en función de cuan exacto quieras que sea la búsqueda. Pero básicamente es como ha dicho #6.

Busca simple, grafo, pondera y palante.

bLero

Y por supuesto el indexado es un must, estaría bien usar Solar, Lucene o en base de datos índices como PG_TRGM (Postgres).

JuAn4k4

Has llegado a mirar SOLR ?

Tiene también aspectos como SOUNDEX que comprueban palabras parecidas por sonido, pero también juega con el hecho de que dén más resultados otras palabras con un X% de variación sobre la propia palabra.

Es decir si yo pongo lamvoryini , con un 80% podría buscar con lamborgini (cambia 2 letras) que daría más resultados.

De verdad, SOLR solucionaria TODOs tus problemas. Si el usuario busca "moto to wapa y reshulona", solr buscará todas las palabras (quitando las stopwords) e incluso buscando sinónimos (en los que puedes añadir más).

Por ejemplo, si estas haciendo un buscador para shurmanos, puedes poner:
wapa -> chula,bonita
reshulona -> resultona
moto -> motocicleta

y hacer que un usuario que busque : moto to' wapa y reshulona, esté buscando:
moto o motocicleta bonita y resultona

Si además, "barata" no se encuentra, no pasa nada, simplemente el resultado que contenga más palabras tendrá más puntuación, asi se ordenan por "score" (o por otros aspectos).
Tu puedes definir cómo se puntuan las busquedas : Si encuentras la palabra en el titulo le das x5, si esta en la descripción x1 , si esta en las etiquetas x5, etc...

De verdad que merece mucho la pena mirartelo con más detenimiento.

1 respuesta
B

Como dice #13 cualquier cosa chula sobre Lucene como SOLR te va a arreglar la vida y no vas a tener que andar haciendo malabarismos.

Hay un motor de búsqueda nuevo sobre Lucene mucho más sencillo de implementar (funciona con JSON para absolutamente todo) y supuestamente es más rapido, Elastic Search

http://www.elasticsearch.org/

Echale un ojo, yo tengo ya el culo pelao con SOLR y es lo que uso casi siempre, pero lo poco que he probado de ES me ha dejado con muy buen sabor de boca.

20 días después
Tunnecino

Por no crear un hilo nuevo, estoy usando Elastic en Symfony con FoS ElasticaBundle, pero tengo bastantes problemas con serializer y los Accessor, alguien ha usado ambos?

Usuarios habituales