搜索引擎
Redrock Postgres 提供了全文检索的能力,通过全文检索可以搭建文本内容搜索引擎。在本节中,我们以网页文本内容为例,介绍如何在 PostgreSQL 中快速建立一个网页文本内容的搜索引擎。
创建网页数据表,用于存储网页的内容数据:
CREATE TABLE IF NOT EXISTS site_page (
id serial PRIMARY KEY,
url text,
image text,
title text,
content text
);
其中表site_page
包括的列如下:
名称 | 描述 |
---|---|
id |
网页的编号 |
url |
网页的链接地址 |
image |
网页图片的链接地址 |
title |
网页的标题 |
content |
网页的正文 |
创建网页内容索引数据表,用于存储网页内容的索引数据:
CREATE TABLE IF NOT EXISTS site_page_tsi (
id integer,
title tsvector,
content tsvector
);
CREATE INDEX site_page_title_idx ON site_page_tsi USING GIN (title);
CREATE INDEX site_page_content_idx ON site_page_tsi USING GIN (content);
其中表site_page_tsi
包括的列如下:
名称 | 描述 |
---|---|
id |
网页的编号 |
title |
网页标题的分词列表 |
content |
网页正文的分词列表 |
当然,您也可以将表
site_page
和site_page_tsi
合并成一个表。在这里,我们更推荐您将网页内容数据和内容索引数据分开存储,这样可以提升网页内容数据的查询性能,也方便单独对索引数据进行维护和调整。通过将内容索引数据独立成一个表,我们可以查看这部分数据的存储空间占用量。另外,我们也可以在添加网页数据时,对内容相关的分词索引项进行优化调整,去除那些我们不感兴趣的关键词,这样做既能节省存储空间,也能提升全文检索的效率。
我们可以添加一条网页数据到表site_page
中,并同时添加一条分词索引记录到表site_page_tsi
中:
BEGIN;
INSERT INTO site_page (url, image, title, content) VALUES
('https://doc.rockdata.net/zh-cn/',
'https://doc.rockdata.net/brand.svg',
'Redrock Postgres 文档',
'Redrock Postgres 是一款基于 PostgreSQL 的关系型数据库管理系统,
Redrock Postgres 主要为企业生产环境和多云环境部署而设计。')
RETURNING id;
id
----
1
INSERT INTO site_page_tsi (id, title, content) VALUES
(1,
to_tsvector('chinese', 'Redrock Postgres 文档'),
to_tsvector('chinese',
'Redrock Postgres 是一款基于 PostgreSQL 的关系型数据库管理系统,
Redrock Postgres 主要为企业生产环境和多云环境部署而设计。'));
COMMIT;
在上面的例子中,我们将一条网页内容数据添加到表site_page
中,获取该条网页内容的编号,然后通过函数to_tsvector
生成网页内容的分词索引,指定对应的网页编号,插入到内容索引数据表site_page_tsi
中。
当然,我们可以根据搜索关键词,检索匹配的网页内容。比如我们可以执行下面的查询,检索网页标题匹配关键词"红石文档"的相关网页数据:
SELECT sp.id, sp.url, sp.title
FROM site_page AS sp
LEFT JOIN site_page_tsi AS tsi ON sp.id = tsi.id
WHERE tsi.title @@ plainto_tsquery('chinese', 'Redrock文档');
查询结果:
id | url | title
----+---------------------------------+----------------
1 | https://doc.rockdata.net/zh-cn/ | Redrock Postgres 文档
上面的例子比较简单。通常来说,在指定搜索关键词检索网页内容时,可能会返回很多匹配的网页数据,此时,您可以考虑通过在查询中指定 LIMIT … OFFSET … 对返回的结果集进行分页展示。