Re: error al usar variable text

From: Gabriel Ferro <gabrielrferro(at)yahoo(dot)com(dot)ar>
To: Gunnar Wolf <gwolf(at)gwolf(dot)org>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: error al usar variable text
Date: 2009-01-31 19:14:51
Message-ID: 153917.33330.qm@web52109.mail.re2.yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

----- Mensaje original ----
> De: Gunnar Wolf <gwolf(at)gwolf(dot)org>
> Para: Gabriel Ferro <gabrielrferro(at)yahoo(dot)com(dot)ar>
> CC: pgsql-es-ayuda(at)postgresql(dot)org
> Enviado: sábado 31 de enero de 2009, 13:43:23
> Asunto: Re: [pgsql-es-ayuda] error al usar variable text
>
> Gabriel Ferro dijo [Fri, Jan 30, 2009 at 12:53:43PM -0800]:
> > Alvaro, lo de hacer un nuevo mensaje no te entiendo, creo que el asunto es
> correcto.
> > Segundo, plainto_tsquery no me sirve ya que no me da lo mismo
> > ejemplo
> > select 'hola coco'::tsvector;
> > Rta: 'coco' 'hola'
> > select plainto_tsquery('hola:coco');
> > Rta: 'hol' & 'coc'
>
> Es que no es lo mismo un tsvector y un tsquery - El tsvector es la
> manera en que representas el contenido de un registro de manera
> adecuada para la búsqueda en texto completo. Por ejemplo, de las
> primeras líneas de tu correo:
>
> gw=# select to_tsvector('spanish', '> Alvaro, lo de hacer un nuevo mensaje
> no te entiendo, creo que el asunto es corre
> gw'# > Segundo, plainto_tsquery no me sirve ya que no me da lo mismo
> gw'# > ejemplo
> gw'# ');
>
> to_tsvector
>
>
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------
> 'da':27 'cre':11 'hac':4 'corr':16 'mism':29 'nuev':6 'sirv':22 'alvar':1
> 'asunt':14 'ejempl':30 'mensaj':7 'plaint':18 'segund':17 'entiend':10
> 'tsquery':19
> (1 row)
>
> Parece desordenado, pero eso porque sólo eres un humano. Puedes ver,
> por ejemplo, que aparece la partícula 'alvar':1 - Eso significa que
> una palabra cuya raiz es 'alvar' ('Alvaro', quitando la mayúscula y la
> 'o' que es indicativa de género) está en primer posición, y si haces
> una búsqueda ordenada sobre 'Alvaro', tu correo debe aparecer como más
> relevante que uno en el que éste nombre aparezca más
> adelante... Claro, siempre que aparezca sólo una vez (porque en este
> caso no se nota, pero las palabras duplicadas aparecen con más de un
> número).
>
> Notarás también que yo le especifiqué como primer argumento que mi
> consulta sería en español. Si lo omito, supongo que PostgreSQL la hace
> dependiendo del entorno en que sea llamado (en Unix, dependiendo de
> $LC_ALL o $LANG). Mi equipo usa localización en inglés, por lo que:
>
> gw=# select to_tsvector('> Alvaro, lo de hacer un nuevo mensaje no te
> entiendo, creo que el asunto es corre
> gw'# > Segundo, plainto_tsquery no me sirve ya que no me da lo mismo
> gw'# > ejemplo
> gw'# ');
>
> to_tsvector
>
>
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> 'da':27 'de':3 'el':13 'es':15 'lo':2,28 'te':9 'un':5 'ya':23 'que':12,24
> 'corr':16 'creo':11 'sirv':22 'hacer':4 'mismo':29 'nuevo':6 'alvaro':1
> 'asunto':14 'mensaj':7 'ejemplo':30 'plainto':18 'segundo':17 'tsqueri':19
> 'entiendo':10
> (1 row)
>
> el resultado es mucho más largo (lo cual _no_ es bueno). Si
> especificas el lenguaje, el motor Snowball de TSearch va a hacer lo
> posible por eliminar las partículas que no significan nada por ser
> demasiado frecuentes (preposiciones, artículos, etc.) y buscar las
> raíces léxicas. Puedes ver que en este caso, 'Alvaro' conserva la 'o'
> que le confiere el género (y disculpa que te tome como ejemplo - Tú te
> lo ganas por responder siempre ;-) ), porque en inglés esta 'o' sería
> parte de la raiz. Si guardas tus tsvectors analizados en inglés, una
> búsqueda sobre 'ejemplar' no va a coincidir con tu 'ejemplo'.
>
> Bueno, ¿y tsquery?
>
> Tsquery es ua estructura que te permite construir explícitamente
> búsquedas a realizar sobre campos tsvector. No tiene sentido almacenar
> un tsquery - debes buscar convertir a tsquery lo que tu usuario te
> pida. Por ejemplo, si quieres buscar mensajes acerca de optimización
> de índices en tablas grandes:
>
> comas=# select plainto_tsquery('spanish', 'optimización de índices en
> tablas grandes');
> plainto_tsquery
> ----------------------------------------
> 'optimiz' & 'indic' & 'tabl' & 'grand'
> (1 row)
>
> Antes de otra cosa, mira qué resulta si nuevamente omito el 'spanish':
>
> comas=# select plainto_tsquery('optimización de índices en tablas
> grandes');
> plainto_tsquery
> -------------------------------------------------------------
> 'optimización' & 'de' & 'índice' & 'en' & 'tabla' & 'grand'
> (1 row)
>
> ¿te queda más claro por qué explicitar el lenguaje?
>
> Bueno, plainto_tsquery() te convierte a tsquery una cadena de texto
> arbitrario, y muchas veces es lo que quieres ofrecer al usuario - pero
> tsquery tiene un pequeño lenguaje que te permite gran riqueza por
> medio de expresiones lógicas. Por ejemplo, posiblemente encuentres
> varias redacciones que te lleven a lo mismo - Buscas optimización de
> índices si quieres acelerar las búsquedas o mejorar la velocidad de
> acceso, ¿cierto? Pero como ya hiciste tu tarea y leíste _todos_ los
> mensajes de Álvaro, quieres ignorar esos resultados. Va, pues:
>
> gw=# select to_tsquery('((optimización & de & índices | acelerando & las &
> busquedas | velocidad & de & acceso ) & tablas & grandes) & ! alvaro');
>
> to_tsquery
>
> ----------------------------------------------------------------------------------------------------------------------------------------------
> ( ( 'optimización' & 'de' & 'índice' | 'acelerando' & 'las' & 'busqueda' )
> | 'velocidad' & 'de' & 'acceso' ) & 'tabla' & 'grand' & !'alvaro'
> (1 row)
>
> Claro, toca al programador desarrollar la interfaz adecuada para
> permitir estas búsquedas a los usuarios ;-) to_tsquery() es mucho más
> potente que plainto_tsquery(), pero requiere pensarle un poquito más.
>
> Espero que con esto te quede más claro.
>
> > la funcion que me da el error es
> > SELECT clave,datos,vectordatos
> > FROM personas,
> > to_tsquery('FERRO&GABRIEL') AS q
> > WHERE vectordatos @@ q and
> > ('Ocupa:Empleado':: tsquery @@ datos::tsvector)
> > ORDER BY ts_rank_cd(vectordatos,q) DESC;
> >
> > al intentar hacer datos::tsvector y encontrar un : cargado en datos
> >
> > pense en reemplazar datos::tsvector por
> > regexp_replace( datos, E'[\\s\'|:&()!]+',' ','g')::tsvector;
> >
> > pero que haga esto por cada fila que compara me parece que hara la
> > consulta mas lenta. ¿considere todos los caracteres raros?. ¿que les
> > parece?
>
> Creo que esto viene de no usar un lenguaje significativo... La cadena
> 'ocupa:empleado' no tendría sentido para TSearch2, de hecho:
>
> comas=# SELECT to_tsvector('spanish', 'ocupa:empleado');
> to_tsvector
> --------------------
> 'ocup':1 'emple':2
> (1 row)
>
> (y si busco sin 'spanish', da 'ocupa' y 'empleado'). Para esta
> búsqueda, te sugiero una de dos: O normalizas la ocupación
> convirtiéndola en una referencia a otra tabla (con lo que puedas decir
> 'AND ocupacion_id = 1'), o para esto haces una búsqueda textual sobre
> los resultados (esto es, WHERE vectordatos @@ q AND datos like
> '%Ocupa:Empleado%') - TSearch no está hecho más que para búsquedas de
> texto "tokenizado" en palabras independientes, descartando todos los
> caracteres no alfanuméricos.
>
> Saludos,
>
> --
> Gunnar Wolf - gwolf(at)gwolf(dot)org - (+52-55)5623-0154 / 1451-2244
> PGP key 1024D/8BB527AF 2001-10-23
> Fingerprint: 0C79 D2D1 2C4E 9CE4 5973 F800 D80E F35A 8BB5 27AF
> --

A la pucha... no si cuando alguien tiene energias y le encanta ayudar... en verdad Gunnar. me tienes sorprendido y te agradezco enormemente el esfuerzo de explicarme tan detalladamente la cosa...mil y una gracias...
De todas maneras me queda la duda de tus ultimos parrafos por el problema de los caracteres especiales... vi algunos posibles aplicaciones de tsearch para el uso de busquedas en textos de paginas web, blog,etc... pero si es recomenable para esto.. y considerando que los textos pueden tener cualquier cosa (incluyendo estos queridos y odiados caracteres) como lo hacen en estos casos?. ¿almacenan el texto sin caracteres especiales para luego realizar las busquedas alli?.. o usan el LIKE como vos indicas?... me parece raro que no exista alguna funcion del tsearch o del postgres que arregle esto y que su implementacion siga siendo mas rapida que usando LIKE.

Mil gracias de nuevo y un abrazo...

Yahoo! Cocina
Recetas prácticas y comida saludable
http://ar.mujer.yahoo.com/cocina/

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Gunnar Wolf 2009-01-31 19:37:16 Re: error al usar variable text
Previous Message Leonardo Alberto Fagua Merchan 2009-01-31 17:20:43