Wörterbücher für Volltextsuche mit PostgreSQL erstellen

Aus Synology Wiki
Wechseln zu: Navigation, Suche

Einleitung

Die PostgreSQL-Datenbank bietet eine recht ausgefeilte Unterstützung für Volltextsuchen (Quelle). Leider liefert Synology keine Konfigurationen mit, die eine nichttriviale Abbildung auf Lexeme ermöglichten. Abhilfe ist möglich und Thema dieses Artikels.

Laden von hunspell-Wörterbüchern

Genauer gesagt wird eine Möglichkeit vorgestellt, PostgreSQL-Wörterbücher für Volltextsuche mit der ispell-Vorlage anzulegen. Erster Schritt ist das Laden und Vorbereiten von hunspell-Wörterbüchern. Basis des folgenden Shell-Skripts ist hier.

#!/bin/sh

BASE=http://src.chromium.org/svn/trunk/deps/third_party/hunspell_dictionaries/
cd /usr/share/postgresql/tsearch_data

if [ ! -e  en_us.dict -o ! -e en_us.affix ]; then
	wget ${BASE}en_US.dic
	wget ${BASE}en_US.dic_delta
	wget ${BASE}en_US.aff -O en_us.affix

	# Remove first line
	sed -i 1d en_US.dic

	# Concat the dic and dic_delta, sort alphabetically
	# and remove the leading blank line (leaves the ending newline intact)
	cat en_US.dic en_US.dic_delta | sort > en_us.dict
	sed -i 1d en_us.dict

	# clean up
	rm en_US*
fi

if [ ! -e de_de.dict -o ! -e de_de.affix ]; then
	curl ${BASE}de_DE_neu.dic | piconv -f latin1| sed 1,2d > de_DE_neu.dic #remove first two lines
	curl ${BASE}de_DE_neu.dic_delta | piconv -f latin1 > de_DE_neu.dic_delta
	curl ${BASE}de_DE_neu.aff | piconv -f latin1 | sed 1s/ISO8859-1/UTF-8/ > de_de.affix

	# Concat the dic and dic_delta, sort alphabetically
	# and remove the leading blank line (leaves the ending newline intact)
	cat de_DE_neu.dic de_DE_neu.dic_delta | sort| sed 1d > de_de.dict

	# clean up
	rm de_DE_neu*
fi

# Set permissions
chown -R postgres:postgres *

Dieses Skript lädt deutsche und englische Wörterbücher und bereitet sie für PostgreSQL vor. Das Laden kann etwas länger dauern, da die Dateien bis zu 10 MB gross und der Server etwas träge sein kann. Für die deutschen Wörterbücher ist eine Recodierung von latin1 zu UTF-8 nötig. Da Synology leider iconv nicht mitliefert, wird das im Skript von dem Progrämmchen piconv übernommen, das z.B. als einfaches python-Skript implementiert werden kann:

#!/usr/bin/python

import fileinput
import argparse

parser = argparse.ArgumentParser()

parser.add_argument('files', nargs='*', help='list of files. If empty, reads stdin. Also reads stdin if "-"  is given as filename')
parser.add_argument("-f", "--from", dest='enc_from', help="encoding of old file(s)", required=True)
parser.add_argument("-t", "--to", help="encoding of new file", default="utf-8")

args = parser.parse_args()

for line in fileinput.input(args.files):
	print(line.decode(args.enc_from).encode(args.to), end='')

Installation in PostgreSQL

In PostgreSQL müssen dann in der Datenbank, in der die Wörterbücher installiert werden sollen, jeweils die folgenden Kommandos ausgeführt werden (Quelle):

--english
CREATE TEXT SEARCH DICTIONARY ispell_en_us (template  = ispell, dictfile = en_us, afffile = en_us, stopwords = english);

CREATE TEXT SEARCH CONFIGURATION english (COPY = pg_catalog.simple);
ALTER TEXT SEARCH CONFIGURATION english ALTER MAPPING FOR asciiword, asciihword, hword_asciipart, word, hword, hword_part WITH ispell_en_us, pg_catalog.simple;

--german
CREATE TEXT SEARCH DICTIONARY ispell_de_de (template  = ispell, dictfile = de_de, afffile = de_de, stopwords = german);

CREATE TEXT SEARCH CONFIGURATION german (COPY = pg_catalog.simple);
ALTER TEXT SEARCH CONFIGURATION german ALTER MAPPING FOR asciiword, asciihword, hword_asciipart, word, hword, hword_part WITH ispell_de_de, pg_catalog.simple;

Sollen die Wörterbücher z.B. in die Datenbank postgres installiert werden, kommt man mit von der Shell mit

psql -U admin postgres

in den passenden SQL-Interpreter.