You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2019-11-27-busqueda-texto-completo-postgresql.markdown
+33-23Lines changed: 33 additions & 23 deletions
Original file line number
Diff line number
Diff line change
@@ -1,38 +1,48 @@
1
1
---
2
2
layout: post
3
-
title: "Búsquedas de texto con Postgresql"
3
+
title: "Búsquedas de texto completo con PostgreSQL"
4
4
date: 2019-11-27 9:00:00
5
5
author: ugaitz
6
6
categories: sql,postgre,base de datos,bbdd
7
-
tags: sql,postgre,base de datos,bbdd
7
+
tags: sql,postgre,base de datos,bbdd,postgresql,fulltext
8
8
header-image: post-headers/data.jpg
9
9
---
10
10
11
-
Hay veces en los que nos encontramos con la necesidad de buscar un registro en una base de datos partiendo de alguna palabra que uno de los campos de la tabla contiene. Si la búsqueda que queremos realizar es muy sencilla, normalmente será suficiente con hacer un _LIKE_ en la consulta. Pero si la consulta que queramos realizar es un poco compleja, veremos que utilizar _LIKE_ no será viable.
11
+
Hay veces en los que nos encontramos con la necesidad de buscar un registro en una base de datos partiendo de alguna palabra que uno de los campos de la tabla contiene. Si la búsqueda que queremos realizar es muy sencilla, normalmente será suficiente con hacer un _LIKE_ en la consulta. Pero si la consulta que queremos realizar es un poco compleja, veremos que utilizar _LIKE_ no será viable.
12
+
13
+
En este artículo mostraremos algunas de las limitaciones de _LIKE_ y de que otras opciones disponemos en PostgreSQL.
14
+
15
+
Si queremos ejecutar estas consultas y no tenemos un postgre instalado en nuestra máquina local, podremos hacerlo fácilmente docker:
Escribiremos `exit` para salir, y podremos borrar el contenedor con el el comando `docker rm -f postgres-full-text`
12
22
13
23
## Buscar con _LIKE_
14
24
Cuando queremos buscar una sola palabra sobre un texto _natural_, como podría ser el contenido de una noticia, la búsqueda con _LIKE_ se complica ya que hay muchos matices que hay que tener en cuenta:
15
25
16
26
- Si buscamos utilizando _LIKE '%palabra%'_ la consulta también devolverá palabras que contengan lo que se ha buscado, en este ejemplo se ve que si buscamos _texto_ en _contexto_, nos devuelve true.
- Si le añadimos unos espacios para que sea _LIKE '% palabra %'_, cuando la palabra que buscamos está al final de una frase terminando con un punto _(.)_ o es un texto inicial, no lo encontrará:
25
35
26
36
```
27
-
SELECT 'texto texto.' LIKE '% texto %' as contiene
37
+
SELECT 'texto texto.' LIKE '% texto %' as contiene;
Para que este tipo de búsqueda de texto funcione correctamente, tendríamos que utilizar una expresión complicada que haría que nuestra consulta tardara más de lo debido. Y además de esta complejidad, ¿que pasa con las palabras en singular o plural? ¿Cuanto se nos complicaría la expresión para realizar estas búsquedas correctamente?
41
+
Para que este tipo de búsqueda de texto funcione correctamente, tendríamos que utilizar una expresión complicada que haría que nuestra consulta tardara más de lo debido. Y además de esta complejidad, ¿Qué pasa con las palabras en singular o plural? ¿Cuánto se nos complicaría la expresión para realizar estas búsquedas correctamente?
32
42
33
43
## Buscar con _tsvector_ y _tsquery_
34
44
35
-
Para solucionar este tipo de problemas se suele recurrir a herramientas como _Elastic search_. Pero si tenemos una base de datos _PostgreSQL_ y no necesitamos todo el potencial de este tipo de herramientas, en Postgresql nos encontramos con un tipo de dato que podría evitarnos quebraderos de cabeza.
45
+
Para solucionar este tipo de problemas se suele recurrir a herramientas como _Elastic search_. Pero si tenemos una base de datos _PostgreSQL_ y no necesitamos todo el potencial de este tipo de herramientas, desde PostgreSQL 8.3 nos encontramos con un tipo de dato que podría evitarnos quebraderos de cabeza.
36
46
37
47
### tsvector
38
48
@@ -70,67 +80,67 @@ SELECT to_tsquery('comer') as english, to_tsquery('spanish','comer') as spanish;
En este caso, el verbo _comer_ lo ha modificado también a _com_, lo que hará que al buscar _comer_ en un texto donde pone _comía_ lo encuentre. Para realizar busquedas, utilizaremos dos arrobas _(@@)_ entre _tsvector_ y _tsquery_
83
+
En este caso, el verbo _comer_ lo ha modificado también a _com_, lo que hará que al buscar _comer_ en un texto donde pone _comía_ lo encuentre. Para realizar búsquedas, utilizaremos dos arrobas _(@@)_ entre _tsvector_ y _tsquery_
74
84
75
85
```
76
-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer') as encontrado
86
+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer') as encontrado;
Si tuvieramos una tabla _documentos_ con una columna _documento_tsvector_ de tipo _tsvector_ y quisieramos encontrar solamente los registros con la palabra _comer_, podríamos hacerlo la siguiente forma:
91
+
Si tuvieramos una tabla _documentos_ con una columna _documento_tsvector_ de tipo _tsvector_ y quisiéramos encontrar solamente los registros con la palabra _comer_, podríamos hacerlo la siguiente forma:
82
92
83
93
```
84
-
SELECT * FROM documentos WHERE documento @@ tsquery('spanish', 'comer')
94
+
SELECT * FROM documentos WHERE documento @@ tsquery('spanish', 'comer');
85
95
```
86
96
87
-
_tsquery_ ofrece multiples posibilidades a la hora de buscar, aquí ponemos los que nos parecen más relevantes:
97
+
_tsquery_ ofrece múltiples posibilidades a la hora de buscar, aquí ponemos los que nos parecen más relevantes:
88
98
89
99
-_and (&)_: Si queremos que el texto contenga varias palabras
90
100
91
101
```
92
-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer & feliz') as encontrado
102
+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer & feliz') as encontrado;
0 commit comments