# 第 18 章 配套代码

本章演示 **PostGIS 地理查询**、**pgvector RAG 语义检索**、**pg_cron 定时任务**、**pg_trgm 模糊搜索**等扩展生态实战。所有自建表都加了 `ch18_` 前缀（`ch18_poi`、`ch18_docs`、`ch18_goods`），避免和其他章节冲突。

## 准备工作

1. 跑一次 init.sql 初始化基础扩展和测试表：

   ```bash
   psql -h 127.0.0.1 -U postgres -d learn_pg -f ../init.sql
   ```

   会启用内置扩展（pg_trgm、pgcrypto、btree_gin、tablefunc、unaccent），并尝试启用 PostGIS 与 pgvector（装了才建对应的表）。

2. **每个脚本依赖的扩展不同**，请按需安装：

   | 脚本 | 必需扩展 | 安装命令（Ubuntu） |
   |------|---------|------------------|
   | `01_extensions_inventory.py` | 无 | （只读 `pg_extension`） |
   | `02_postgis_nearby.py` | `postgis` | `apt install postgresql-XX-postgis-3` 后 `CREATE EXTENSION postgis;` |
   | `03_pgvector_rag.py` | `vector` | 源码编译 [pgvector](https://github.com/pgvector/pgvector) 后 `CREATE EXTENSION vector;` |
   | `04_pg_cron_demo.py` | `pg_cron` | `apt install postgresql-XX-cron`，并把 `pg_cron` 加到 `shared_preload_libraries`，重启后 `CREATE EXTENSION pg_cron;` |
   | `05_pg_trgm_search.py` | `pg_trgm`（内置） | `CREATE EXTENSION pg_trgm;`（init.sql 已做） |

3. 安装 Python 依赖：

   ```bash
   pip install "psycopg[binary]>=3.1"
   # 03 脚本可选：用真实 sentence-transformers 嵌入模型（不装则用伪向量演示）
   pip install sentence-transformers
   ```

4. （可选）通过环境变量覆盖默认连接：

   ```bash
   export PG_DSN="host=127.0.0.1 port=5432 dbname=learn_pg user=postgres password=postgres"
   ```

## 脚本一览（推荐运行顺序）

| 脚本 | 一句话说明 | 关键 PG 特性 |
|------|------------|--------------|
| `01_extensions_inventory.py` | 列出当前库已装/可装扩展，看清楚生态全景 | `pg_extension`、`pg_available_extensions` |
| `02_postgis_nearby.py` | 用 `ch18_poi` 演示「天安门附近 1km 内有哪些咖啡店」 | `geography`、`ST_DWithin`、GiST 索引 |
| `03_pgvector_rag.py` | 把若干文档转成 384 维向量灌进 `ch18_docs`，做语义检索 | `vector(384)`、HNSW / IVFFlat、`<=>` 余弦距离 |
| `04_pg_cron_demo.py` | 注册 3 个示例 cron 任务（`ch17_perf_orders` 上的 VACUUM/ANALYZE/DELETE） | `cron.schedule_in_database`、`cron.job` |
| `05_pg_trgm_search.py` | 用 `ch18_goods` 演示 `LIKE '%xxx%'` 走 GIN trigram 索引 | `gin_trgm_ops`、`similarity()`、`%` 阈值 |

## 预期输出（节选 02）

```
🔍 距天安门 1km 内的 cafe（按距离升序）：
  · POI #1283   distance=  213 m
  · POI #4517   distance=  587 m
  · POI #2031   distance=  834 m
  ...
```

## 常见报错与依赖

- `connection refused` → PG 未启动。
- `extension "postgis" is not available` → 没装 PostGIS 系统包，参见上面的安装表。
- `extension "vector" is not available` → 没装 pgvector，源码编译后再 `CREATE EXTENSION vector;`。
- `pg_cron must be loaded via shared_preload_libraries` → 改 `postgresql.conf`，加上 `shared_preload_libraries='pg_cron'` 与 `cron.database_name='learn_pg'`，重启 PG。
- `relation "ch18_poi" does not exist` → init.sql 跑的时候 PostGIS 没装，跳过了建表；装好 PostGIS 后重跑 init.sql。
- 03 用 sentence-transformers 时首次会下模型，需要 ≥ 1GB 显存或较长 CPU 等待；脚本提供「伪向量回退」分支。
