81 lines
2.5 KiB
Markdown
81 lines
2.5 KiB
Markdown
# enrich_fulltext_v1.0
|
|
|
|
**Verze:** 1.0
|
|
**Datum:** 2026-06-03
|
|
**Skript:** `enrich_fulltext_v1.0.py`
|
|
|
|
## Účel
|
|
Pro každý dokument odkazovaný v MongoDB (`soubory.*`) vytáhne **plný text** a uloží do PostgreSQL s GIN `tsvector` indexem pro fulltext vyhledávání.
|
|
|
|
## Cíl: PostgreSQL `MongoSoubory`
|
|
- **host:** 192.168.1.76:5432
|
|
- **db:** `MongoSoubory`
|
|
- **user:** vladimir.buzalka
|
|
- **extension:** `unaccent`, `pg_trgm`
|
|
- **text search config:** `soubory` (= simple + unaccent → case- a diakritika-insensitivní)
|
|
|
|
## Tabulka `documents`
|
|
| sloupec | typ | popis |
|
|
|---|---|---|
|
|
| id | BIGSERIAL | PK |
|
|
| mongo_id | TEXT | ObjectId z Mongo |
|
|
| study | TEXT | kolekce v Mongo (`42847922MDD3003` / `77242113UCO3001`) |
|
|
| path | TEXT | absolutní cesta (UNIQUE s study) |
|
|
| rel_path, name, ext | TEXT | doplňková metadata |
|
|
| sha256 | TEXT | pro inkrementální kontrolu |
|
|
| size_bytes, mtime | | |
|
|
| **body** | TEXT | plný extrahovaný text (max 5 MB) |
|
|
| body_length | INT | délka v znacích |
|
|
| **tsv** | tsvector GENERATED STORED | `to_tsvector('soubory', body)` |
|
|
| extracted_at | TIMESTAMPTZ | čas extrakce |
|
|
| extractor_version | TEXT | verze tohoto skriptu |
|
|
| ok | BOOLEAN | true pokud extrakce proběhla |
|
|
| error | TEXT | chybové hlášení |
|
|
|
|
**Indexy:** GIN nad `tsv`, GIN trigram nad `name`, btree `sha256`, btree `(study, ext)`.
|
|
|
|
## Podporované přípony
|
|
`pdf`, `docx`, `xlsx`, `xlsm`, `pptx`, `eml`, `msg`, `txt`, `csv`
|
|
|
|
## Inkrementální chování
|
|
Soubor se přeskočí pokud v PG už existuje záznam s:
|
|
- shodným `sha256`
|
|
- shodnou `extractor_version`
|
|
- `ok = true`
|
|
|
|
Jinak se přeparsuje a UPSERT.
|
|
|
|
## Limity (skip s `error=too_big_...`)
|
|
- PDF nad 500 MB
|
|
- XLSX nad 200 MB
|
|
- ostatní nad 300 MB
|
|
- `body` se vždy ořízne na 5 MB UTF-8
|
|
|
|
## Příklady dotazů (psql)
|
|
```sql
|
|
-- fulltext (case+diakritika insensitivní)
|
|
SELECT study, name, ts_rank_cd(tsv, q) AS rank,
|
|
ts_headline('soubory', body, q, 'MaxFragments=2,MinWords=5,MaxWords=15') AS snippet
|
|
FROM documents, plainto_tsquery('soubory', 'amendment 3') q
|
|
WHERE tsv @@ q
|
|
ORDER BY rank DESC
|
|
LIMIT 20;
|
|
|
|
-- jméno obsahuje (trigram, fuzzy)
|
|
SELECT study, name FROM documents
|
|
WHERE name ILIKE '%protokol%';
|
|
|
|
-- nejdelsi dokumenty per studie
|
|
SELECT study, name, body_length
|
|
FROM documents
|
|
WHERE ok = true
|
|
ORDER BY body_length DESC LIMIT 10;
|
|
```
|
|
|
|
## Spuštění
|
|
```
|
|
python U:\PythonProject\Janssen\Soubory\enrich_fulltext_v1.0.py
|
|
```
|
|
|
|
Průběh tiskne řádek na soubor: `[n/total] OK pdf 2.3MB protokol.pdf | 12340 znaku 'Protocol amendment ...'`
|