pgpdf

PDF数据类型,管理函数与全文检索

概览

扩展包名版本分类许可证语言
pgpdf0.1.0TYPEGPL-3.0C
ID扩展名BinLibLoadCreateTrustReloc模式
3530pgpdf-
相关扩展pgjq pgjwt prefix semver unit pglite_fusion md5hash asn1oid

版本

类型仓库版本PG 大版本包名依赖
EXTPIGSTY0.1.01817161514pgpdf-
RPMPIGSTY0.1.01817161514pgpdf_$v-
DEBPIGSTY0.1.01817161514postgresql-$v-pgpdf-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
d12.aarch64
d13.x86_64
d13.aarch64
u22.x86_64
u22.aarch64
PIGSTY 0.1.0
PIGSTY 0.1.0
PIGSTY 0.1.0
PIGSTY 0.1.0
PIGSTY 0.1.0
u24.x86_64
u24.aarch64
PIGSTY 0.1.0
PIGSTY 0.1.0
PIGSTY 0.1.0
PIGSTY 0.1.0
PIGSTY 0.1.0

构建

您可以使用 pig build 命令构建 pgpdf 扩展的 RPM / DEB 包:

pig build pkg pgpdf         # 构建 RPM / DEB 包

安装

您可以直接安装 pgpdf 扩展包的预置二进制包,首先确保 PGDGPIGSTY 仓库已经添加并启用:

pig repo add pgsql -u          # 添加仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

pig install pgpdf;          # 当前活跃 PG 版本安装
pig ext install -y pgpdf -v 18  # PG 18
pig ext install -y pgpdf -v 17  # PG 17
pig ext install -y pgpdf -v 16  # PG 16
pig ext install -y pgpdf -v 15  # PG 15
pig ext install -y pgpdf -v 14  # PG 14
dnf install -y pgpdf_18       # PG 18
dnf install -y pgpdf_17       # PG 17
dnf install -y pgpdf_16       # PG 16
dnf install -y pgpdf_15       # PG 15
dnf install -y pgpdf_14       # PG 14
apt install -y postgresql-18-pgpdf   # PG 18
apt install -y postgresql-17-pgpdf   # PG 17
apt install -y postgresql-16-pgpdf   # PG 16
apt install -y postgresql-15-pgpdf   # PG 15
apt install -y postgresql-14-pgpdf   # PG 14

预加载配置

shared_preload_libraries = 'pgpdf';

创建扩展

CREATE EXTENSION pgpdf;

用法

实际的 PDF 解析由 poppler 完成。

该扩展允许以符合 ACID 事务的方式处理 PDF 文件。 常见的替代方案依赖于外部脚本或服务,容易导致数据摄取流程变得脆弱,并使原始数据出现不同步的问题。

下载一些 PDF 文件。

wget https://wiki.postgresql.org/images/e/ea/PostgreSQL_Introduction.pdf -O /tmp/pgintro.pdf
wget https://pdfobject.com/pdf/sample.pdf -O /tmp/sample.pdf

通过将 text 类型的文件路径或 bytea 列进行类型转换,即可创建 pdf 类型。

CREATE EXTENSION pgpdf;
SELECT '/tmp/pgintro.pdf'::pdf;
                                       pdf
----------------------------------------------------------------------------------
 PostgreSQL Introduction                                                         +
 Digoal.Zhou                                                                     +
 7/20/2011Catalog                                                                +
  PostgreSQL Origin

如果文件系统中没有 PDF 文件,但已将其内容存储在 bytea 列中,可以直接将其转换为 pdf 类型。

SELECT pg_read_binary_file('/tmp/pgintro.pdf')::bytea::pdf;

示例

创建一个包含 pdf 列的表:

CREATE TABLE pdfs(name text primary key, doc pdf);

INSERT INTO pdfs VALUES ('pgintro', '/tmp/pgintro.pdf');
INSERT INTO pdfs VALUES ('pgintro', '/tmp/sample.pdf');

解析和验证会自动进行。 文件只会从磁盘读取一次!

字符串函数和运算符

标准的 PostgreSQL 字符串函数和运算符均可正常使用:

SELECT 'Below is the PDF we received ' || '/tmp/pgintro.pdf'::pdf;
SELECT upper('/tmp/pgintro.pdf'::pdf::text);
SELECT name
FROM pdfs
WHERE doc::text LIKE '%Postgres%';

全文搜索(FTS)

由于 pdf 文件可以像普通文本一样操作,因此也支持全文搜索(FTS)。

SELECT '/tmp/pgintro.pdf'::pdf::text @@ to_tsquery('postgres');
 ?column?
----------
 t
(1 row)
SELECT '/tmp/pgintro.pdf'::pdf::text @@ to_tsquery('oracle');
 ?column?
----------
 f
(1 row)

使用 pg_trgm 计算文档相似度

可以使用 pg_trgm 计算两个文档之间的相似度:

CREATE EXTENSION pg_trgm;

SELECT similarity('/tmp/pgintro.pdf'::pdf::text, '/tmp/sample.pdf'::pdf::text);

元数据

以下函数可用:

  • pdf_title(pdf) → text

  • pdf_author(pdf) → text

  • pdf_num_pages(pdf) → integer

    文档的总页数

  • pdf_page(pdf, integer) → text

    获取第 i 页的文本内容

  • pdf_creator(pdf) → text

  • pdf_keywords(pdf) → text

  • pdf_metadata(pdf) → text

  • pdf_version(pdf) → text

  • pdf_subject(pdf) → text

  • pdf_creation(pdf) → timestamp

  • pdf_modification(pdf) → timestamp

SELECT pdf_title('/tmp/pgintro.pdf');
        pdf_title
-------------------------
 PostgreSQL Introduction
(1 row)
SELECT pdf_author('/tmp/pgintro.pdf');
 pdf_author
------------
 周正中
(1 row)

获取部分页面

SELECT pdf_num_pages('/tmp/pgintro.pdf');
 pdf_num_pages
---------------
            24
(1 row)
SELECT pdf_page('/tmp/pgintro.pdf', 1);
           pdf_page
------------------------------
 Catalog                     +
  PostgreSQL Origin         +
  Layout                    +
  Features                  +
  Enterprise Class Attribute+
  Case
(1 row)
SELECT pdf_subject('/tmp/pgintro.pdf');
 pdf_subject
-------------

(1 row)
SELECT pdf_creation('/tmp/pgintro.pdf');
       pdf_creation
--------------------------
 Wed Jul 20 11:13:37 2011
(1 row)
SELECT pdf_modification('/tmp/pgintro.pdf');
     pdf_modification
--------------------------
 Wed Jul 20 11:13:37 2011
(1 row)
SELECT pdf_creator('/tmp/pgintro.pdf');
            pdf_creator
------------------------------------
 Microsoft® Office PowerPoint® 2007
(1 row)
SELECT pdf_metadata('/tmp/pgintro.pdf');
 pdf_metadata
--------------

(1 row)
SELECT pdf_version('/tmp/pgintro.pdf');
 pdf_version
-------------
 PDF-1.5
(1 row)

安装

安装 poppler 依赖

Linux

sudo apt install -y libpoppler-glib-dev pkg-config

Homebrew/MacOS

brew install poppler pkgconf
cd /tmp
git clone https://github.com/Florents-Tselai/pgpdf.git
cd pgpdf
make
make install # 可能需要 sudo

安装完成后,在数据库会话中执行:

CREATE EXTENSION pgpdf;

Docker

通过以下命令获取 Docker 镜像

docker pull florents/pgpdf:pg17

此镜像在 Postgres 镜像 基础上添加了 pgpdf(将 17 替换为所需的 Postgres 服务器版本,运行方式相同)。

在容器中运行该镜像。

docker run --name pgpdf -p 5432:5432 -e POSTGRES_PASSWORD=pass florents/pgpdf:pg17

通过另一个终端连接到正在运行的服务器(容器)。

PGPASSWORD=pass psql -h localhost -p 5432 -U postgres

最后修改 2026-03-08: add extension catalog (baacba6)