Skip to content

Commit 73a0fff

Browse files
committed
Referencia a docker y fixes
1 parent 4cb9eef commit 73a0fff

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

_posts/2019-11-27-busqueda-textos-postgresql.markdown renamed to _posts/2019-11-27-busqueda-texto-completo-postgresql.markdown

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,48 @@
11
---
22
layout: post
3-
title: "Búsquedas de texto con Postgresql"
3+
title: "Búsquedas de texto completo con PostgreSQL"
44
date: 2019-11-27 9:00:00
55
author: ugaitz
66
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
88
header-image: post-headers/data.jpg
99
---
1010

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:
16+
17+
```
18+
docker run -d --name postgres-full-text postgres
19+
docker exec -it postgres-full-text psql -U postgres
20+
```
21+
Escribiremos `exit` para salir, y podremos borrar el contenedor con el el comando `docker rm -f postgres-full-text`
1222

1323
## Buscar con _LIKE_
1424
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:
1525

1626
- 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.
1727

1828
```
19-
SELECT 'contexto' LIKE '%texto%' as contiene
29+
SELECT 'contexto' LIKE '%texto%' as contiene;
2030
```
2131

2232
![contiene1](/assets/images/2019-10-03-busqueda-textos-postgresql/contiene-1.png){: .center }
2333

2434
- 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á:
2535

2636
```
27-
SELECT 'texto texto.' LIKE '% texto %' as contiene
37+
SELECT 'texto texto.' LIKE '% texto %' as contiene;
2838
```
2939
![contiene2](/assets/images/2019-10-03-busqueda-textos-postgresql/contiene-2.png){: .center }
3040

31-
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?
3242

3343
## Buscar con _tsvector_ y _tsquery_
3444

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.
3646

3747
### tsvector
3848

@@ -70,67 +80,67 @@ SELECT to_tsquery('comer') as english, to_tsquery('spanish','comer') as spanish;
7080

7181
![contiene2](/assets/images/2019-10-03-busqueda-textos-postgresql/murcielagohindu-3.png){: .center }
7282

73-
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_
7484

7585
```
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;
7787
```
7888

7989
![contiene2](/assets/images/2019-10-03-busqueda-textos-postgresql/encontrado.png){: .center }
8090

81-
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:
8292

8393
```
84-
SELECT * FROM documentos WHERE documento @@ tsquery('spanish', 'comer')
94+
SELECT * FROM documentos WHERE documento @@ tsquery('spanish', 'comer');
8595
```
8696

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:
8898

8999
- _and (&)_: Si queremos que el texto contenga varias palabras
90100

91101
```
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;
93103
```
94104
![encontrado](/assets/images/2019-10-03-busqueda-textos-postgresql/encontrado.png){: .center }
95105

96106
```
97-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer & triste') as encontrado
107+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer & triste') as encontrado;
98108
```
99109
![contiene2](/assets/images/2019-10-03-busqueda-textos-postgresql/noencontrado.png){: .center }
100110

101111
- _or_ (\|): Si queremos que el texto contenga una de las palabras
102112

103113
```
104-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer | triste') as encontrado
114+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'comer | triste') as encontrado;
105115
```
106116
![encontrado](/assets/images/2019-10-03-busqueda-textos-postgresql/encontrado.png){: .center }
107117

108118
```
109-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'cenar | triste') as encontrado
119+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'cenar | triste') as encontrado;
110120
```
111121
![no encontrado](/assets/images/2019-10-03-busqueda-textos-postgresql/noencontrado.png){: .center }
112122

113123
- _<->_: Si queremos que tenga dos palabras consecutivas
114124

115125
```
116-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <-> murciélago') as encontrado
126+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <-> murciélago') as encontrado;
117127
```
118128
![encontrado](/assets/images/2019-10-03-busqueda-textos-postgresql/encontrado.png){: .center }
119129

120130
```
121-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <-> hindú') as encontrado
131+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <-> hindú') as encontrado;
122132
```
123133
![no encontrado](/assets/images/2019-10-03-busqueda-textos-postgresql/noencontrado.png){: .center }
124134

125-
- _&lt;N&gt;_: Si buscamos dos palabras que esten a una distancia de _N_
135+
- _&lt;N&gt;_: Si buscamos dos palabras que estén a una distancia de _N_
126136

127137
```
128-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <2> hindú') as encontrado
138+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <2> hindú') as encontrado;
129139
```
130140
![encontrado](/assets/images/2019-10-03-busqueda-textos-postgresql/encontrado.png){: .center }
131141

132142
```
133-
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <3> hindú') as encontrado
143+
SELECT to_tsvector('spanish','El veloz murciélago hindú comía feliz cardillo y kiwi') @@ to_tsquery('spanish', 'veloz <3> hindú') as encontrado;
134144
```
135145
![no encontrado](/assets/images/2019-10-03-busqueda-textos-postgresql/noencontrado.png){: .center }
136146

@@ -153,7 +163,7 @@ SELECT ts_rank(to_tsvector('spanish','El veloz canguro australiano comía feliz
153163
Para aplicar _ts_rank_ en una consulta, podríamos hacerlo de la siguiente manera.
154164

155165
```
156-
SELECT * FROM documentos ORDER BY ts_rank(document, tsquery('spanish', 'comer')) DESC
166+
SELECT * FROM documentos ORDER BY ts_rank(document, tsquery('spanish', 'comer')) DESC;
157167
```
158168

159-
[textsearch-documentation]: https://www.postgresql.org/docs/9.6/functions-textsearch.html
169+
[textsearch-documentation]: https://www.postgresql.org/docs/current/textsearch.html

0 commit comments

Comments
 (0)