zim

.zim-(Kiwix-/openZIM-)Archive direkt in DuckDB über libzim lesen, von lokalen Dateien oder remote über S3/HTTP — Offline-Wikipedia, WikiMed, Stack Exchange, iFixit und mehr, mit einem zim://-Dateisystem und Volltextsuche.

Maintainer: teaguesterling

Installation und Laden

INSTALL zim FROM community;
LOAD zim;

Beispiel

-- Load the extension
LOAD zim;
-- List every content entry in an archive (one row per entry).
-- A listing scan is lazy: it never decompresses the article bodies.
SELECT path, title, mimetype FROM read_zim('wikipedia.zim') LIMIT 10;
-- A bare FROM on a .zim file is rewritten via a replacement scan.
SELECT count(*) FROM 'wikipedia.zim';
-- Read across many archives at once: a glob or a LIST of paths.
SELECT * FROM read_zim('archives/*.zim');
SELECT * FROM read_zim(['wikimed.zim', 'wikipedia.zim']);
-- Read a remote archive over S3/HTTP (LOAD httpfs first): byte-range requests
-- fetch only the bytes a query touches, not the whole multi-GB file.
SELECT zim_main_entry('https://dumps.wikimedia.org/.../wikipedia_en_simple.zim');
-- Narrow the scan: exact lookup, prefix listing, or a mimetype filter.
SELECT * FROM read_zim('wikipedia.zim', path := 'A/Berlin');
SELECT * FROM read_zim('wikipedia.zim', title_prefix := 'Aspirin');
SELECT * FROM read_zim('wikipedia.zim', mimetype := 'text/html');
-- Bulk content, gated by mimetype: only matching entries are decompressed,
-- everything else keeps its row with NULL content (pushdown, not a filter).
SELECT path, content FROM read_zim('wikipedia.zim', include_content := 'text/html');
-- The zim:// filesystem: any path-reading function can address an entry inside
-- the archive (read_text / read_blob, or webbed's read_html, etc.).
SELECT * FROM read_text('zim://wikipedia.zim/A/Berlin');
SELECT * FROM read_blob('zim://wikipedia.zim/I/logo.png');
SELECT * FROM read_text('zim://wikipedia.zim/A/B*'); -- glob over content paths
-- Full-text search over the archive's Xapian index.
SELECT path, title, score, snippet
FROM zim_search('wikipedia.zim', 'photosynthesis', max_results := 20);
-- Search a REMOTE archive without downloading it: the Xapian index is read in
-- place via byte-range requests (a cold query fetches a fraction of a %, not the
-- whole multi-GB file). with_snippet := false skips fetching result bodies.
SELECT path, title FROM zim_search(
'https://download.kiwix.org/zim/.../wikipedia_en_medicine.zim',
'insulin', max_results := 10, with_snippet := false);
-- Title autocomplete (works on every build, incl. WebAssembly).
SELECT path, title FROM zim_suggest('wikipedia.zim', 'Photosyn');
-- Federated: search across a whole shelf at once (glob or LIST); the `file`
-- column says which archive each hit came from.
SELECT file, path, title FROM zim_search('library/*.zim', 'insulin', max_results := 5);
-- Single-entry access, metadata, and utilities.
SELECT zim_get_text('wikipedia.zim', 'A/Berlin');
SELECT zim_main_entry('wikipedia.zim');
SELECT * FROM read_zim_metadata('wikipedia.zim');
SELECT zim_counter('wikipedia.zim'); -- mimetype -> count histogram
SELECT zim_info('wikipedia.zim'); -- counts, flags, uuid
SELECT zim_illustration('wikipedia.zim'); -- cover image / favicon (BLOB)
SELECT zim_random('wikipedia.zim'); -- a random entry's path
SELECT zim_check('wikipedia.zim'); -- integrity check

Über zim

Die Erweiterung zim liest .zim-Dateien — das Archivformat von openZIM, ausgeliefert von Kiwix — direkt in DuckDB. ZIM packt eine ganze Website in eine einzelne komprimierte, inhaltsadressierte Datei: Offline-Wikipedia, WikiMed, Wiktionary, Project Gutenberg, Stack Exchange, iFixit, TED und Hunderte weiterer Bibliotheken. Diese Erweiterung macht jedes solche Archiv zu einer per SQL abfragbaren Tabelle — oder zu einem abfragbaren Dateisystem — ohne es zu entpacken.

Archive lesen: read_zim() liefert eine Zeile pro Inhaltseintrag — path, title, mimetype und den (lazy materialisierten) content. Der Scan unterstützt Projektions-Pushdown und lazy Content: eine Abfrage, die nur die Auflistung prüft, dekomprimiert niemals Artikelkörper. Zeigen Sie auf eine einzelne Datei, ein Glob oder eine LIST(VARCHAR), um viele Archive auf einmal zu lesen; ein bloßes FROM 'archive.zim' wird automatisch über einen Replacement Scan umgeschrieben. Grenzen Sie den Scan durch exakte Suche (path / title), Präfixlisting (path_prefix / title_prefix), einen mimetype-Filter oder listing := 'path' | 'title' ein. include_content akzeptiert einen Mimetype oder eine Liste von Mimetypes, um Inhalt nur für gewünschte Einträge zu dekomprimieren, und Prädikate WHERE path/title/mimetype werden in libzim durchgereicht.

Lokal oder remote: Archive werden aus lokalen Dateien oder — mit geladenem httpfs — direkt von S3/HTTP über Byte-Range-Requests gelesen. Eine Abfrage gegen ein mehrere GB großes Remote-Archiv holt nur die berührten Bytes; kürzlich genutzte Remote-Handles bleiben zwischen Aufrufen warm.

Das Dateisystem zim://: ein schreibgeschütztes Dateisystem registriert zim://, sodass jede pfadlesende Funktion — DuckDBs eigene read_text / read_blob oder webbeds read_html oder alles andere, das durch die Dateischicht geht — einen Eintrag in einem Archiv adressieren kann (zim://wikipedia.zim/A/Photosynthesis), einschließlich Globs. Weiterleitungen lösen sich wie Symlinks auf. So setzt sich das gesamte Ökosystem über ZIM-Inhalte zusammen, ohne Kopplung und ohne GPL-Verknüpfung in jene Erweiterungen.

Volltextsuche und Vorschläge: wenn das Archiv einen Xapian-Index mitführt, fragt zim_search() ihn ab und liefert (path, title, score, snippet, file) nach Relevanz sortiert; zim_suggest() liefert Titel-Autocomplete und funktioniert in jedem Build (fällt ohne Xapian auf ein Titel-Präfixlisting zurück und ist daher auch auf WebAssembly verfügbar, wo Volltextsuche nicht möglich ist). Beide sind föderiert: das erste Argument kann ein einzelner Pfad, ein Glob oder eine LIST sein, sodass eine Abfrage über viele Archive gleichzeitig läuft.

Metadaten, Skalare und Hilfen: read_zim_metadata(), zim_metadata() / zim_metadata_keys(), zim_counter() (das selbstbeschreibende Mimetype-Histogramm) und zim_info() (Zählungen, Flags, uuid); plus zim_get_content / zim_get_text, zim_has_entry, zim_redirect_target, zim_mimetype, zim_main_entry, zim_illustration (Titelbild), zim_random und zim_check (Integrität).

Jede VARCHAR-Ausgabe ist binärsicher — Nicht-UTF-8-Bytes kommen als NULL zurück statt verstümmelt zu werden. Aufgebaut auf libzim; Lizenz GPL-2.0-or-later, übernommen von libzim.

Hinzugefügte Funktionen

function_name function_type description comment examples
read_zim table NULL NULL
read_zim_metadata table NULL NULL
zim_check scalar NULL NULL
zim_counter scalar NULL NULL
zim_get_content scalar NULL NULL
zim_get_text scalar NULL NULL
zim_has_entry scalar NULL NULL
zim_illustration scalar NULL NULL
zim_info scalar NULL NULL
zim_main_entry scalar NULL NULL
zim_metadata scalar NULL NULL
zim_metadata_keys scalar NULL NULL
zim_mimetype scalar NULL NULL
zim_random scalar NULL NULL
zim_redirect_target scalar NULL NULL
zim_search table NULL NULL
zim_suggest table NULL NULL

Überladene Funktionen

Diese Erweiterung fügt keine Funktionsüberladungen hinzu.

Hinzugefügte Typen

Diese Erweiterung fügt keine Typen hinzu.

Hinzugefügte Einstellungen

name description input_type scope aliases
zim_max_content_size Maximum decompressed size (bytes) of a single ZIM entry to materialize; reads of a larger entry fail cleanly instead of allocating (decompression-bomb guard). 0 disables the cap. Lower it when reading untrusted archives. UBIGINT GLOBAL []
zim_remote_search_max_local_index Maximum size (bytes) of a remote ZIM’s full-text index to copy locally so search works; 0 disables remote search. Larger values cover bigger archives but lengthen the first remote search (the whole index is fetched once). UBIGINT GLOBAL []