Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

[SOLUCIONADO] Excluir palabras de una consulta

Estas en el tema de Excluir palabras de una consulta en el foro de Mysql en Foros del Web. Hola, Con la siguiente consulta busco en el texto de mi_columna todas las palabras que empiezan por $mi_busqueda @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código SQL: Ver original SELECT ...
  #1 (permalink)  
Antiguo 08/05/2013, 20:32
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Excluir palabras de una consulta

Hola,

Con la siguiente consulta busco en el texto de mi_columna todas las palabras que empiezan por $mi_busqueda
Código SQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2. WHERE mi_columna REGEXP '([[:<:]]".$mi_busqueda.")'

Ahora, lo que no llego lograr es como ampliar este REGEXP para que no devuelva verdadero cuando encuentra solo las coincidencias de $mi_busqueda con ciertas palabras que quiero excluir
Cita:
Editado: Codigo de programación no permitido en foros de Bases de Datos.
O sea si encuentra una o mas palabras NO Excluidas y una o mas palabras Excluidas que devuelva verdadero

pero si encuentra solo las palabras excluidas que devuelva falso

Gracias por anticipado

Última edición por gnzsoloyo; 08/05/2013 a las 20:54
  #2 (permalink)  
Antiguo 09/05/2013, 01:45
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Excluir palabras de una consulta

La idea es esta , pero no he probado nada.

Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2.     WHERE mi_columna REGEXP '([[:<:]]".$mi_busqueda.")' AND $mi_busqueda NOT IN ('palabra1', 'palabra2', 'palabra3')
Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2.     WHERE mi_columna REGEXP '([[:<:]]".$mi_busqueda.")'  AND mi_columna NOT REGEXP 'palabra1|palabra2|palabra3';

Pero no sé por qué necesitas usar expresiones regulares para eso si quizás no es necesario y las expresiones no son muy eficientes. Esta sería la idea
Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2.     WHERE mi_columna LIKE '@mi_busqueda%' AND @mi_busqueda NOT IN ('palabra1', 'palabra2', 'palabra3')
  #3 (permalink)  
Antiguo 09/05/2013, 04:24
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

Cita:
Iniciado por jurena Ver Mensaje
La idea es esta , pero no he probado nada.

Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2.     WHERE mi_columna REGEXP '([[:<:]]".$mi_busqueda.")' AND $mi_busqueda NOT IN ('palabra1', 'palabra2', 'palabra3')
Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2.     WHERE mi_columna REGEXP '([[:<:]]".$mi_busqueda.")'  AND mi_columna NOT REGEXP 'palabra1|palabra2|palabra3';

Pero no sé por qué necesitas usar expresiones regulares para eso si quizás no es necesario y las expresiones no son muy eficientes. Esta sería la idea
Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2.     WHERE mi_columna LIKE '@mi_busqueda%' AND @mi_busqueda NOT IN ('palabra1', 'palabra2', 'palabra3')
Muchas gracias por responder.
He probado tus sugerencias , estan correctas ( o sea funcionan ) pero ninguna no me da el resultado deseado.

Tambien he leido muchas veces esto que las expresiones regulares son lentas pero no se que otra cosa utilizar para obtener lo mismo pero sin usarlas.

Pongo aqui mi pseudo codigo como ejemplo ( o sea lo que quiero que haga la consulta ) y si tienes alguna sugerencia ... Bienvenida sea

Mis palabras excluidas:
Código:
$palabras_excluidas = array('para','palabra2','palabra3');
Mi busqueda:
Código:
$mi_busqueda='par';
Supongamos que mi_columna contiene las siguientes filas:
Cita:
1. "algo para estar acaparado"
2. "parachoques rotos para coches"
3. "alguien que esta parado"

Algoritmo Condiciones:
Cita:
1. Se comprueba cada palabra de mi_columna (no solo el principio de la frase) si hay palabras que empiezan por "par" descartando las que contiene pero no al principio (ej: "acaparado")

2. Al encontrar palabra que empieza con "par" se compara dicha palabra (palabra entera esta vez ) ej "para" o "paracoches" con el array $palabras_excluidas


3. Si en el punto 2. se encuentran solo palabras excluidas se considera respuesta NO VALIDA y descarta esta fila

4. Si en el punto 2 se encuentran palabras excluidas pero también NO Excluidas se considera respuesta VALIDA y se agrega esta fila a la respuesta

5. Si en el punto 2 se encuentran solo palabras No Excluidas se considera respuesta VALIDA y se agrega esta fila a la respuesta
Mi respuesta deseada es:
que la consulta me devuelva las filas 2 y 3
porque la fila 2 al tener al menos una palabra "parachoques" que empieza por "par" que es $mi_busqueda no la descarte del resultado aunque tenga la palabra "para" que esta en las excluidas

y la fila 3 tiene una palabra "parado" que empieza con "par" aunque no esta al principio de la frase

y que no devuelva la fila 1 porque "acaparado" no empieza por "par" y aunque tiene otra palabra "para" que si empieza por "par" pero esta entre las excluidas y al no tener al menos una palabra valida que empieze por "par" que la descarte del resultado.

Ahora ... no importa la solucion que sea por REGEXP o no o hibrida ... importante seria el resultado.

Espero que se entienden mis dudas

Otra vez gracias por haber ya respondido
  #4 (permalink)  
Antiguo 09/05/2013, 05:50
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Excluir palabras de una consulta

Yo le veo dos soluciones posibles mas o menos simples, basadas en lo que dice jurena:
Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2. WHERE mi_columna LIKE CONCAT(' ', '$mi_busqueda, '%');


Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2. WHERE INSTR(CONCAT(' ', '$mi_busqueda'), mi_columna) > 0;

Si me equivoco en algún detalle de sintaxis, disculpen. No tengo el MySQL a mano para ponerme a probar.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 09/05/2013, 08:25
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Si me equivoco en algún detalle de sintaxis, disculpen. No tengo el MySQL a mano para ponerme a probar.
Gracias por responder,

Lo de los detalles de la sintaxis eran lo de menos .... entiendo que uno pueda faltar alguna coma o comillas etc... cuando escribe de memoria ... pero al probar y estudiar mejor el problema ... creo .... de verdad ... que en este caso ... LIKE ... no puede servir!

A no ser que yo no entiendo bien y aunque reconozco, no sabia nada de CONCAT (ni siquiera que existe) ... al leer un poco por la web me doy cuenta que lo que me estabas sugiriendo

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2. WHERE mi_columna LIKE CONCAT(' ', '$mi_busqueda', '%');
es lo mismo que :

Código MySQL:
Ver original
  1. SELECT mi_id FROM mi_tabla
  2. WHERE mi_columna LIKE ' ".$mi_busqueda."%';

Cosa que no me sirve de NADA !!!

Al hacer la consulta de esta manera no devuelve nada ( a no ser que no haya una fila que empiece por un espacio seguido de $mi_busqueda) lo que tampoco sirve

La segunda sugerencia PEOR ! No devuelve nunca nada ( aunque la sintaxis es correcta )

Gracias de todos modos por responderme ya que me has hecho descubrir CONCAT e INSTR ... pero desafortunadamente no me sirven (he mirado con la misma ocasion tambien SUBSTRING ) pero tampoco sirve

¿Algun otra ideea?


(para que se entienda mejor lo que estoy planteando mirar el post mas arriba en el cual explico en detalle )

http://www.forosdelweb.com/f86/excluir-palabras-consulta-1050578/#post4426345

EDITADO:
(he intentado emplear las etiquetas url del foro pero agregan automaticamente una noparse que esta liando los links ... asi que he pegado el url como texto ... sorry)

Saludos y gracias

Última edición por matake; 09/05/2013 a las 08:54
  #6 (permalink)  
Antiguo 09/05/2013, 08:56
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Excluir palabras de una consulta

volveré a escribir la consulta.
Una pregunta antes de hacer lo fácil algo más difícil. ¿Tu motor de base de datos es MyIsam o InnoDB? Si tu tabla es MyIsam, lo resolveremos muy fácilmente con FULL-TEXT. Si no probaremos de otro modo. Dinos lo que tienes.

Última edición por jurena; 09/05/2013 a las 09:35 Razón: he borrado porque había un error
  #7 (permalink)  
Antiguo 09/05/2013, 09:16
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Excluir palabras de una consulta

Cita:
he intentado emplear las etiquetas url del foro pero agregan automaticamente una noparse que esta liando los links ... asi que he pegado el url como texto ... sorry
No tienes suficiente antigüedad ni cantidad de mensajes para que puedas poner link o imágenes. Restricciones que puedes leer en las Políticas de Uso de FDW, link al pie de la pagina.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 09/05/2013 a las 10:47
  #8 (permalink)  
Antiguo 09/05/2013, 10:06
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

Cita:
Iniciado por jurena Ver Mensaje
volveré a escribir la consulta.
¿Tu motor de base de datos es MyIsam o InnoDB? Si tu tabla es MyIsam, lo resolveremos muy fácilmente con FULL-TEXT.
Lo que tengo es MyIsam.

..... en lo que recomiendas ... consultas FULL-TEXT .... he leido un poco aunque no tengo experiencia ..... y no me he atrevido resolver este problema por no saber dominar este tipo de consultas

..... Agradecería su propuesta y si no se puede por MyIsam ... tambien podria pasar a InnoDB ( si no hay remedio ) ya que estoy en la fase de empiezar un proiecto.



Saludos

Cita:
Iniciado por gnzsoloyo Ver Mensaje
No tienes suficiente antigüedad ni cantidad de mensajes para quye puedas poner link o imágenes. Restricciones que puedes leer en las Políticas de Uso de FDW, lonk al pie de la pagina
Politicas leidas .... Mis disculpas sorry

Saludos
  #9 (permalink)  
Antiguo 09/05/2013, 11:16
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Excluir palabras de una consulta

Esto es con regexp para InnoDB. Te pongo la lógica:
mediante union all me traigo aquellos registros que tienen la palabra para y que a la vez tiene par o par+ dos o más caracteres
eso lo uno a todos aquellos registros que no tienen la palabra para y sí la cadena par con algo por delante o por detrás.

Observa las dificultades, pero funcionar funciona, aunque es solo para la palabra para. Voy a probar con FULL-TEXT y si puedo te lo escribo en este mismo post.
Código MySQL:
Ver original
  1. (
  2. SELECT id, campo
  3. FROM tabla
  4. WHERE campo
  5. REGEXP '[[:<:]]para[[:>:]]' =1
  6. AND (
  7. campo
  8. REGEXP 'par[a-zA-Z]{2,}'
  9. OR campo
  10. REGEXP '[[:<:]]par[[:>:]]' =1
  11. OR campo
  12. REGEXP 'par(b|c|d|e|f|g|h|i|j|k|l|m|n|ñ|o|p|q|r|s|t|u|w|x|y|z).*'
  13. )
  14. )
  15.  
  16. SELECT id, campo
  17. FROM tabla
  18. WHERE campo
  19. REGEXP '[[:<:]]para[[:>:]]' =0
  20. AND campo LIKE '%par%'
  21. )
  #10 (permalink)  
Antiguo 09/05/2013, 15:17
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

Cita:
Iniciado por jurena
Observa las dificultades, pero funcionar funciona,
Hola jurena, lo siento pero NO. No funciona

Por muy compleja que es ... te lo juro me he quedado como ... wwwaaauuuu ...
cuando he visto lo que acabas de postear arriba y creo que te costo bastante trabajo para hacerlo ... pero de las tres filas de ejemplo que he puesto en mi ejemplo arriba ... saca las tres .... o sea igual que yo tenia al principio con una sola linea

Código MySQL:
Ver original
  1. SELECT id, campo FROM tabla
  2. WHERE campo REGEXP '([[:<:]]".$mi_busqueda.")'

donde $mi_busqueda podria ser "p","pa","par" o "para" ... pues hacia lo mismo sacaba las tres filas ( del ejemplo que di en mi segundo post ) or yo esperaba que solo muestre las filas 2 y 3 y no la fila 1

Bueno, pero si que me diste buenas pistas pero después de tres .... casi cuatro horas creo ... sin parar sobre este asunto he llegado a una lógica mas simple aunque no me funciona por tener un error en la sintaxis haber si me puedes ayudar a repararlo

Mi logica inspirado en tu respuesta anterior :
Código MySQL:
Ver original
  1. (
  2.     SELECT id, campo
  3.     FROM tabla
  4.     WHERE
  5.  
  6. /*muestra las filas que contienen palabras que empiezan por $mi_busqueda */
  7.     campo REGEXP '[[:<:]]".$mi_busqueda."' =1
  8.  
  9. /*no muestra las filas que no contienen palabras que empiezan por $mi_busqueda y  tienen la palabra entera "para" */
  10.     NOT
  11.     (campo REGEXP '[[:<:]]".$mi_busqueda."'=0 AND
  12.     campo REGEXP '[[:<:]]para[[:>:]]' =1)
  13. )
  14.  
  15. /*Aunque por separado si que hacen lo que se supone no logro que trabajen conjunto por un error de sintaxis */

Como lógica no creo que estaría mal pero al no tener experiencia este ejemplo me arroja ahora un error de sintaxis "You have an error in your SQL syntax; check the manual .... "

Aunque llevo buscando y probando ... no lo consigo

Curioso es que por separado si dejo la primera sentencia .... funciona ... y si dejo la segunda .... ( la de NOT ) ... tambien funciona .... o sea .... creo que es una cosa muy muuuyyyy basica de sintaxis pero no llego resolver

Gracias y disculpen por estar un poco pesado
  #11 (permalink)  
Antiguo 09/05/2013, 19:43
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Excluir palabras de una consulta

Me gustaría volver a tu algoritmo descripto para hacerte una reflexión:
Cita:
1. Se comprueba cada palabra de mi_columna (no solo el principio de la frase) si hay palabras que empiezan por "par" descartando las que contiene pero no al principio (ej: "acaparado")

2. Al encontrar palabra que empieza con "par" se compara dicha palabra (palabra entera esta vez ) ej "para" o "paracoches" con el array $palabras_excluidas

3. Si en el punto 2. se encuentran solo palabras excluidas se considera respuesta NO VALIDA y descarta esta fila

4. Si en el punto 2 se encuentran palabras excluidas pero también NO Excluidas se considera respuesta VALIDA y se agrega esta fila a la respuesta

5. Si en el punto 2 se encuentran solo palabras No Excluidas se considera respuesta VALIDA y se agrega esta fila a la respuesta
Es a mi entender, absolutamente imposible hacer una única consulta que pueda responder a las cinco condiciones al mismo tiempo. Para lograrlo tienes por lo menos, que iterar el resultado del primer paso, para poder resolver el segundo, y no existen consultas iterativas en MySQL.

¿Lo has tenido en cuenta?

Se necesita:

1) Extraer un grupo de N palabras.
2) Comparar las N palabras con una colección de palabras.
3) Si las palabras recolectadas están incluidas totalmente en el segundo conjunto, descartar todo, en caso contrario (los siguientes están lógicamente incluidos), recuperarlo.

El problema es que las dos primeras partes son incompatibles para una consulta, porque no puedes extraer las palabras sin iterar...

Tal vez sea posible hacerlo con un stored procedure, pero yo te recomendaría usar una combinación de programación y consultas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #12 (permalink)  
Antiguo 09/05/2013, 21:04
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

Hola,

Despues de muchas horas ( de verdad muchas ) y gracias a las pistas que me habéis dado he resuelto gran parte de la siguiente forma:
(me queda todavia un problema a la linea 16 )

Código MySQL:
Ver original
  1. /* en php */       
  2. $palabras_excluidas = array("para","palabra2","palabra3"); /* se pueden añadir otras  */
  3.  
  4. $busqueda = "par"; /* tmbien vale "p" "pa" "par" "para" "pal" "pala" "palab" "palabra" "palabra2" "palabra3"
  5. o cualquier otra busqueda */
  6.    
  7. /* el sql */
  8. (
  9.     SELECT id, campo
  10.     FROM tabla
  11.     WHERE
  12.     campo REGEXP '[[:<:]]".$busqueda."'=1 /*devuelve filas que llevan palabras  que empiezan por $busqueda */
  13.     AND NOT(  /* pero no devuelve aquellas filas que contienen cualquiera de las palabras excluidas ... he puesto las palabras excluidas dentro del REGEXP con implode con separador "|" .... */
  14.         campo REGEXP '[[:<:]](".implode('|',$palabras_excluidas).")[[:>:]]' =1
  15.         AND(  /* y si $busqueda es mas pequeña que la palabra excluida pero coincide con el principio de la misma, no la considere como valida   */
  16.             campo REGEXP '[[:<:]]".$q."[a-z|0-9]{2}'=0 /* me queda una duda con {2} razon por la cual todavia no doy por resuelto el tema ... explicaciones mas abajo */
  17.         )
  18.     )
  19. )




Explico aqui lo del {2} de la linea 16 de arriba ... que todavia le falta algo

Para que la busqueda sea siempre correcta el numero dentro de las corchetes tiene que estar siempre igual a: n=count($palabra_encontrada_en_la_fila) - count($busqueda)

Alguien tiene alguna sugerencia?

Saludos

Cita:
Iniciado por gnzsoloyo
Perdona gnzsoloyo ... al estar mucho rato con la ventana de edicion de mensaje abierta sin enviarlo ... vi tu post ahora despues de enviar yo este mismo .

Pues si que el algoritmo por mucho que te parecia como solucion facil al principio cuando me recomandaste lo del CONCAT , esta bastante complicado ... sobre todo para uno como yo que no tengo ni estudios ni experiencia en esto.

Lo que me sorprende es que al final no me ha quedado tan complicado ( esto si si llego a resolver lo que he mencionado arriba ) ....

De toda manera como esta ahora esta bastante bien ( he hecho muchas pruebas y va bien ... excepto lo comentado )

De toda manera ... sin vuestras sugerencias no creo que habia avanzado nada de nada ... asi que otra vez gracias ... y felicitaciones por lo que haceis

Última edición por matake; 09/05/2013 a las 21:37
  #13 (permalink)  
Antiguo 10/05/2013, 00:53
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Excluir palabras de una consulta

Matake, me alegro de que hayas resuelto tu problema. No obstante, quiero hacerte ver las dificultades que entiendo hay en todo. Para empezar, si miras aquí, verás por qué decía que funcionar funciona:
http://sqlfiddle.com/#!2/a4a2c/1

aunque seguramente eso no resuelve todos tus requisitos.
Si me centro únicamente en la palabra 'para',
1) tienes que traerte todos los registros que responden a LIKE '%par%' si no tienen dentro la palabra 'para'
2) los que teniendo la palabra 'para' presentan además la cadena que incluye 'par', pero date cuenta de que la cadena par está incluida en para, por lo que tienes que separar la palabra par, y las que tienen para + algo. De ahí esa necesidad, pensaba yo.

No obstante, si ya lo tienes resuelto, estupendo. Enhorabuena.
  #14 (permalink)  
Antiguo 10/05/2013, 03:17
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

gracias jurena, todavia no se puede cantar victoria .... la "pequeña cosa" que queda es bastante complicada (por ahora)

Tambien quiero aclarar que los comentarios criticos, que a veces hago, los hago de buena honda como se dice y no para criticar a alguien al contrario considero esto un debate constructivo.

Ademas mira por ejemplo gracias a ti he aprendido hoy un monton de cosas que no sabia sobre los REGEXP ... incluso lo de sqlfiddle aunque el jsfiddle lo vi hace unos dias (te has ganado con creces mi punto)


Ok. volviendo al problema ...

Cita:
Iniciado por jurena
1) tienes que traerte todos los registros que responden a LIKE '%par%' si no tienen dentro la palabra 'para'
la solucion mas simple para hacer esto es lo que tenia al principio

Código MySQL:
Ver original
  1. (
  2. SELECT id, campo
  3. FROM tabla
  4. WHERE campo
  5. REGEXP '[[:<:]]$busqueda'
  6. )

O sea responde PERFECTAMENTE a tu plantemiento trae todos los que empiezan por "p" "pa" "par" o "para" (en funcion del valor de $busqueda ) sin tener en cuenta los que tienen dentro "p" "pa" "par" "para" etc. ... todo esto con esta linea "REGEXP '[[:<:]]$busqueda' "

Lo de tu punto 2 .... si que es otra cosa ... ademas es justo una parte del problema que tengo ahora que todavia no esta resuelto

O sea resuelto el punto 1 queda esto :

distinguir las palabras que empiezan por $busqueda (sea cual sea su valor "p" "pa" "par" o "para" ) de los que en su totalidad coinciden con alguna del array $palabras_excluidas (en este caso con la palabra "para" )

Es por esto que no doy por resuelto el caso y cualquier sugerencia incluso las que pueden no estar del todo correctas estan bienvenidas.

Saludos y gracias

Última edición por matake; 10/05/2013 a las 03:31
  #15 (permalink)  
Antiguo 10/05/2013, 07:51
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

Hola otra vez

Creo haber encontrado un camino para solucionar el problema de otra manera ( a no ser que por mi ignorancia no me doy cuenta que no se puede )

/\bpara[a-z]{1,}\b/g <-- esta expresion regular devuelve lo siguiente ( probado en refiddle )

Fila 1: algo para estar acaparado Fila 2: parachoques rotos para coches Fila 3: alguien que esta parado

O sea todo el algoritmo que parecia bastante complejo quedaria resuelto por esta linea.

Pregunta : ¿Se puede emplear esta expresion regular en una consulta Mysql? y ¿Como?

Gracias
  #16 (permalink)  
Antiguo 11/05/2013, 12:08
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Excluir palabras de una consulta

No sé si cubrirá todos tus requisitos, pero creo que esta consulta servirá como buen punto de partida. He adaptado la sintaxis que usabas de REGEXP a la propia de MySQL.
Código MySQL:
Ver original
  1. SELECT id, campo
  2. FROM tabla
  3. WHERE campo
  4. REGEXP '[[:<:]][a-z]{0,}para[a-z]{1,}[[:>:]]'

Mataque, creo que si usamos una consulta de este tipo adaptada a la búsqueda, podremos solucionar todo, pero el primer paso es saber si la cadena buscada forma parte de las palabras excluidas. Eso lo resuelves con programación, php o lo que sea. Si no forma parte de ninguna de ellas, esto te bastaría
Código MySQL:
Ver original
  1. SELECT id, campo
  2. FROM tabla
  3. WHERE campo
  4. REGEXP '[[:<:]][a-z]{0,}par[a-z]{0,}[[:>:]]'

pero si forma parte de alguna de ellas, como es el caso de par respecto a para, tienes que cubrir con varios REGEXP unidos por OR todas las posibilidades:
1) una palabra con 'uno o ningún carácter + par'.
2) todas las que tienen 'uno o ningún carácter + par + un carácter distinto de a + ninguno o más caracteres cualquiera.
3) todas las que tienen 'uno o ningún carácer + par+a+más uno o más caracteres'.

Quizás podrías reunir la 1 y 2 en una, pero al menos dos debe haber.

Pero piensa que todo esto se complicará si en lugar de 'par' buscas 'pa' sería algo más complicado.

Y si las búsquedas va a ser del tipo buscar 'pa' pero excluir 'parado', 'panza', 'apalabrado'
entonces yo te recomendaría dejar parte del trabajo al programa con el que tú programas.
Yo haría dos consultas, una con lo seguro, aquellos registros que responden en el where a LIKE '%pa%' AND no se incluye ninguna de las tres palabras (quizás con un índice fulltext, si van a ser palabras de más de 3 caracteres). Eso lo cargaría en otro array específico de resultados definitivos.
La segunda consulta se traería LIKE '%pa%' y además una o varias de esas palabras. Luego mediante programación (PHP, ASP, C++ o el que uses) recorro con funciones (preg_match y preg_match_all por poner un ej. de PHP [puedes pedir ayuda en el foro específico]) y expresiones regulares solo esos registros últimos para comprobar que aparece lo que busco aparte de esas palabras excluidas. Las que pasen este filtro de programación las cargo en el array de resultados definitivos y ya tendré lo que quiero. Piensa que de esa manera las expresiones regulares tan concretas no recorrerán toda la tabla, sino solo los registros que pueden contener los términos excluidos.

Última edición por jurena; 12/05/2013 a las 02:16
  #17 (permalink)  
Antiguo 14/05/2013, 11:43
 
Fecha de Ingreso: mayo-2013
Mensajes: 191
Antigüedad: 10 años, 11 meses
Puntos: 10
Respuesta: Excluir palabras de una consulta

Hola,

Perdonen el retraso pero he querido estar un poco mas seguro a la hora de postear para no alargar mucho la charla.


Gracias jurena por responder ... con un poco suerte y usando algo de logica he llegado a encontrar lo de la equivalencia de /b y [[:<:]] buscando entender porque los testers online no acceptan la expresion [[:<:]] ... incluso abri un tema por esto en el foro regex por si sabe alguien algun tester regex online que accepte esto [[:<:]]

hace unos dias me respondi solo en aquel foro y he dado el tema por resuelto.

Pero de todos modos Gracias jurena ... imaginate que no lo habia encontrado. Tu respuesta me habria sido de gran ayuda.

Ademas tenias razon ... estaba yo equivocado en pensar que solo con esto resolveria mi asunto.

Por esto decidi de mejor tardar un poquito que lanzarme en postear otra y otra vez.

Al final si lo he conseguido ... aqui dejo la solucion por si alguien la necesita o encuentra algun error o alguna mejora:

Código MySQL:
Ver original
  1. SELECT id, campo
  2. FROM tabla
  3.     campo REGEXP '[[:<:]]".$busqueda."'=1
  4.     AND NOT(
  5.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,1)).")[[:>:]]'=1
  6.             AND
  7.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,1)).")[a-z]{1,}[[:>:]]'=0
  8.         OR(
  9.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,2)).")[[:>:]]'=1
  10.             AND
  11.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,2)).")[a-z]{1,}[[:>:]]'=0
  12.         )
  13.         OR(
  14.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,3)).")[[:>:]]'=1
  15.             AND
  16.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,3)).")[a-z]{1,}[[:>:]]'=0
  17.         )
  18.         OR(
  19.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,4)).")[[:>:]]'=1
  20.             AND
  21.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,4)).")[a-z]{1,}[[:>:]]'=0
  22.         )  
  23.         OR(
  24.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,5)).")[[:>:]]'=1
  25.             AND
  26.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,5)).")[a-z]{1,}[[:>:]]'=0
  27.         )              
  28.     )

Explico la parte PHP:

la variable $busqueda puede tomar cualquier valor

La funcion excluidos($busqueda,$nr) me devuelve un array()con todas las palabras excluidas que empiezan por $busqueda y tienen como longitud 1,2,3,4,5 ... caracteres (si no hay ninguna palabra me devuelve el caracter "!" ) ... que luego empleando implode uso "|" como division y sale una cadena asi: para|esta|bien etc ... dependiendo de las palabras excluidas que encuentra ... o si no encuentra ninguna la cadena tendra solo el caracter de exclamacion "!" .
Dicha cadena ayuda la construccion de la expresion regular y saldra algo como:
Código MySQL:
Ver original
  1. campo REGEXP '[[:<:]](para|esta|bien)[a-z]{1,}[[:>:]]'=0
  2.         AND
  3.         campo REGEXP '[[:<:]](para|esta|bien)[[:>:]]' =1
  4.  
  5.  
  6. /* o si no hay palabras .... para evitar errores  saldra asi */
  7.  
  8. campo REGEXP '[[:<:]](!)[a-z]{1,}[[:>:]]'=0
  9.         AND
  10.         campo REGEXP '[[:<:]](!)[[:>:]]' =1

el numero como parametro dentro de la funcion implode("|",excluidos($busqueda,1)) es para buscar palabras excluidos de un caracter como "y" "o" ...
implode("|",excluidos($busqueda,2)) para palabras de dos caracteres como "de" "pe" "si" "no" etc

siguiendo asi con palabras de tres caracteres 4 5 ... etc ... hasta llegar a palabras como "ciclopentanoperhidrofenantreno"

esto si. Siempre hay que añadir un par de consultas para la longitud de la nueva palabra .... por ejemplo si pongo como excluido palabra "estado" ... etc de 6 caracteres tengo que añadir la consulta:
Código MySQL:
Ver original
  1.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,6)).")[[:>:]]'=1
  2.             AND
  3.             campo REGEXP '[[:<:]](".implode("|",excluidos($busqueda,6)).")[a-z]{1,}[[:>:]]'=0
  4.         )

Cosas que se pueden automatizar con programacion

No pongo todavia como solucionado por si se me ha escapado algun error ... pero en unos dias si veo que no hay opiniones lo pondre como resuelto

Doy la gracias otra vez a jurena y gnzsoloyo por su ayuda e ideas


Saludos

Etiquetas: excluir, palabras, regexp
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 07:03.