Redrock Postgres 文档
主页 切换暗/亮/自动模式 切换暗/亮/自动模式 切换暗/亮/自动模式 返回首页

搜索引擎

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_pagesite_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 … 对返回的结果集进行分页展示。