除了用函数之外,还可以用强制类型转换的方式将一个字符串转换成tsvector或tsquery类型,例如 postgres=# select 'fat cats sat on a mat and ate a fat rat'::tsvector; tsvector ----------------------------------------------------- 'a' 'and' 'ate' 'cats' 'fat' 'mat' 'on' 'rat' 'sat' postgres=# select 'a & fat & rats'::tsquery; tsquery ---------------------- 'a' & 'fat' & 'rats'
postgres=# create table post( postgres(# id bigint, postgres(# author name, postgres(# title text, postgres(# body text); CREATE TABLE
– insert some tuples `然后想检索body中含有“physics”或“math”的帖子标题,可以用如下的语句来查询:```sql
1
postgres=# select title from post where to_tsvector(body) @@ to_tsquery('physics | math');
title
The most popular math books `也可以将多个字段组合起来查询:```sql
1
postgres=# select title from post where to_tsvector(title || ' ' || body) @@ to_tsquery('physics | math');
title
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
注意不同的查询方式可能产生不同的结果。例如下面的匹配不成功,因为::tsquery没对检索条件做标准化,前面的tsvector里找不到“cats”这个词: postgres=# select to_tsvector('a fat cat ate fat rats') @@ 'cats & rat'::tsquery; ?column? ---------- f `而同样的文档和检索条件,下面的匹配能成功,因为to_tsquery会把“cats”变成“cat”:```sql postgres=# select to_tsvector('a fat cat ate fat rats') @@ to_tsquery('cats & rat'); t `类似地,下面的匹配不成功,因为to_tsvector会把停用词a去掉:```sql postgres=# select to_tsvector('a fat cat ate fat rats') @@ 'cat & rat & a'::tsquery; f `而下面的能成功,因为::tsvector保留了所有词:```sql postgres=# select 'a fat cat ate fat rats'::tsvector @@ 'cat & rat & a'::tsquery; f
所以应根据需要选择合适的检索方式。 此外,@@操作符可以对输入的text做隐式类型转换,例如,
1
postgres=# select title from post where body @@ 'physics | math';
title
1
(0 rows)
1 2 3 4 5 6 7 8 9 10
准确来讲,text@@text相当于to_tsvector(text) @@ plainto_tsquery(text),因此上面的匹配不成功,因为plainto_tsquery会把或条件'physics | math'变成与条件'physic' & 'math'。使用时要格外小心。 #### 3. 创建和使用索引 前文提到,逐个扫描表中的文本字段缓慢低效,而索引查找能够提高检索的速度和效率。GaussDB(DWS)支持用通用倒排索引GIN(Generalized Inverted Index)进行全文检索。GIN是搜索引擎中常用的一种索引,其主要原理是通过关键字反过来查找所在的文档,从而提高查询效率。可通过以下语句在text类型的字段上创建GIN索引: postgres=# create index post_body_idx_1 on post using gin(to_tsvector('english', body)); CREATE INDEX