Wissensmanagement in der Architekturarbeit, Teil 4
1. Eine Volltextsuchmaschine mit Recoll einrichten
Eines der häufigsten Probleme mit organisch gewachsenen Dokumentenstrukturen ist es, Daten wiederzufinden. Die Fragestellung ist hier, wie finde ich Dokumente, die eine bestimmte Zeichenkette enthalten?
Dafür gibt es verschiedene Lösungsmöglichkeiten. Das Kommandozeilenwerkzeug ´pdfgrep´ ist in der Lage, durch PDF-Dateien zu greppen und liefert so das entsprechende Dokument und die Funstelle im Dokument zurück. Es ist aber nicht in der Lage z.B. durch Word, Excel oder Powerpoint-Dokumente zu suchen.
Abhilfe schafft hier entweder die Konvertierung aller Dokumente in das PDF-Format oder der Einsatz einer spezialisierten Suchmaschine, die auch DOCX und Co. indizieren kann. Da eine solche Suchmaschine nicht nur mit DOCX und Co. nativ umgehen kann sondern auch eine wesentlich schnellere Suche dank Suchindex mitbringt, ist diese Lösung besser als einfach nur pdfgrep
auf der Kommandozeile zu nutzen.
Eine solche Suchmaschine ist Recoll. Recoll setzt auf einer Xapian-Datenbank auf, einer Volltextsuchmaschinenbibliothek die z.B. auch vom Archiv der "Zeit" genutzt wird oder als Backend für die Desktopsuche in Gnome. Xapian kommt mit fortgeschrittenen Such- und Indizier-Funktionen, der Fähigkeit Dokumente sofort zu indizieren und im Index verfügbar zu machen sowie der Unterstützung für sehr große Dokumente. Die Suche ist probabistisch, d.h. Ergebnisse können nach Relevanz sortiert werden und es werden Phrasen- und Ähnlichkeitssuchen unterstützt. Über Aspell kann auch Index-Stemming (Stammformreduktion) durchgeführt werden, dabei werden Wörter auf ihre Stammform im Suchindex zurückgeführt. So werden die Zeichenketten hat gesehen
und sah es
auch unter sehen
indiziert.
Recoll unterstützt auch gepackte/gekapselte Dateien, z.B. eine gezippte HTML-Datei in einer exportierten Outlook-Mail.
Recoll kann auch ein externes OCR-Programm triggern, um PDFs ohne Text-Daten zu scannen und in Text umzuwandeln. Dazu bietet sich bei Bedarf tesseract
an. Da wir hier aber nur selbsterstellte und damit indizierbare PDFs vorliegen haben, ist dieser Schritt nicht nötig.
Sollten denoch PDFs als Scan oder Fotos von Text vorliegen, kann Recoll mit Tesseract versuchen den Text zu erkennen und diesen in den Index aufzunehmen. Die originale PDF wird dabei nicht verändert. Daher ist es wahrscheinlich sinnvoller, die PDF direkt mit OCRmyPDF
in eine durchsuchbare PDF mit Textindex zu konvertieren, so kann man diese auch im PDF-Viewer durchsuchen bzw. Recoll kann direkt auf die Fundstellen verlinken.
Damit ist die Kombination Xapian/Recoll bestens geeignet, einen großen Dokumentenstamm zu durchsuchen.
Recoll ist als Frontend für Xapian eigentlich als persönliche Suchmaschine auf dem Desktop gedacht, kann aber auch in einer etwas eingeschränkteren Version via Apache als Webfrontend eingesetzt werden. Und genau diese Lösung setze ich auf dem dSecurecloud-Server ein.
Auf Debian/Ubuntu lassen sich die benötigten Pakete direkt mit sudo apt -y install recoll python3-recoll apache2 libapache2-mod-wsgi-py3
installieren.
Anschließend cloned man recoll-webui
aus https://framagit.org/medoc92/recollwebui nach /var/www/
und passt die Apache-Konfiguration für WSGI in /etc/apache2/mods-enabled/wsgi.conf
an:
WSGIDaemonProcess recoll user=gitlab-runner group=gitlab-runner\ threads=5 processes=5 display-name=%{GROUP} \ python-path=/var/www/recoll-webui-master WSGIScriptAlias /recoll /var/www/recoll-webui-master/webui-wsgi.py <Directory /var/www/recoll-webui-master> WSGIProcessGroup recoll Require all granted </Directory>
Dabei muss gitlab-runner
durch den Benutzer ersetzt werden, der Eigentümer des Recoll-Index ist. Anschließend ist das Webinterface unter hostname/recoll/
erreichbar.
Im Home-Verzeichnis des Benutzers müssen die zu indizierenden Dokumente liegen. Standardmäßig durchsucht Recoll das gesamte Home und packt den entstehenden Index in ~/.recoll/xapiandb
. Diese Werte kann man in ~/.recoll/recoll.conf
anpassen:
# zu durchsuchende Verzeichnisse
topdirs ~/Dokument/Intern ~/Dokumente/Extern
# Pfad für die Index-Datenbank
dbdir = /mnt/storage/recoll/xapiandb
# auszuschließende Dateinamen/Verzeichnisse
skippedNames *draft* *entwurf*
# Verzeichnisse, die ausgeschlossen werden, wenn sich diese Datei im Verzeichnis befindet:
nowalkfn .norecoll
# max Größe für .txt-Dateien, Standard ist 20MB
textfilemaxmbs 5
# bestimmte Zeichen die beim indizieren nicht zerlegt werden sollen, betrifft vor allem Umlaute und Ligaturen
unac_except_trans = ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae fifi flfl
# Sprachen für das Index-Stemming via Aspell
indexstemminglanguages = english german german2
Will man komplett getrennte Indizes aufbauen, z.B. für verschiedene Arbeitsgruppen AG1 und AG2, kann man deren Verzeichnisse und Index-Datenbanken entsprechend trennen. Dazu legt man getrennte Verzeichnisse an und in diesen jeweils eine eigene Konfiguration, in der mindestens topdirs
und dbdir
auf einen Pfad im jeweiligen Gruppenverzeichnis liegen. Mittels -c /Pfad/zur/.recoll/recoll.conf
kann man dann die jeweilige Konfiguration auf der Befehlszeile übergeben.
Auf dem Server muss man neue Dokumente mittels recollindex
indizieren, damit sie in die Suchmaschine aufgenommen werden. Mit der Option -m
kann die Echtzeitindizierung aktiviert werden, d.g. recollindex
überwacht die konfigurierten Dokumentenverzeichnisse auf Änderungen und indiziert neue Dokumente automatisch.
Da wir neue Dokumente aber über das Gitlab auf den Server bringen, kann recollindex
auch über einen Gitlab-Runner direkt getriggert werden, um den Index bei Bedarf zu erweitern.
1.1. Suchoptionen
Das Recoll-Webinterface bietet nicht die vollen Optionen wie eine lokale Installation. Dennoch ist es hinreichend um Dokumente effizient zu finden.
Im Query-Feld kann eine beliebige Suchanfrage gestellt werden. Reguläre Ausdrücke wie ^Anfang.*Ende$
werden unterstützt.
Unter Dates
können die zu durchsuchende Zeiträume eingeschränkt werden, dies bezieht sich aber auf die mtime
der Datei und leider nicht auf die Metadaten einer PDF. Eine PDF aus dem Jahr 2010 die 2023 ins Gitblab eingecheckt wird, wir für 2023 indiziert und nicht 2010. Daher in unserem Szenario leider nicht sehr hilfreich.
Das selbe gilt für Sort by
. Hier kann das Sortierkriterium angegeben werden. Standardmäßig ist dies die Relevanz, aber auch Dateiname, Autor oder Dateigröße sind möglich. Datum ebenso, aber hier gilt die o.g. Einschränkung auf die Änderungszeit der Datei.
Unter Folder
kann das zu durchsuchende Verzeichnis weiter eingeschränkt werden.
Auf der Ergebnisseite werden die Suchergebnisse gemäß Sortierkriterium angezeigt. Dabei wird der Dateiname und die Autoreninfo sowie der Pfad und die Uhrzeit im Kopf angezeigt. Darunter findet sich ein Auszug aus 30 Wörtern Kontext um die erste Fundstelle herum.
Unter dem Titel bzw. Dateinamen finden sich drei Links, wenn man mit der Maus darüberfährt. Open
funktioniert auf der Webseite leider nicht. Über Download
kann man die verlinkte Datei herunterladen, unter Preview
wird eine Vorschau der Datei als Text geöffnet. Der Suchterm wird dabei farblich hervorgehoben.
Da es Probleme mit der Anzeige des Titels gab, wahrscheinlich durch problematische Metadaten aus dem Sharepoint, habe in der Anzeige der Ergebnisse den Titel deaktiviert, in dem ich in /var/www/recoll-webui-master/webui.py
Zeile 354 title
durch filename
ersetzt habe.
# d['label'] = select([d['title'], d['filename'], '?'], [None, ''])
d['label'] = select([d['filename'], d['filename'], '?'], [None, ''])
1.2. Exkurs: PDFs ohne Text mit OCR durchsuchbar machen
In diesem konkreten Anwendungsfall sind alle PDFs von uns selbst erstellt und entweder mit AsciiDoctor-PDF generiert oder aus Word heraus exportiert und damit als Text durchsuchbar.
Es gibt aber auch PDFs ohne Text-Index, da die Datei beispielweise von einem Scanner erzeugt wurde und lediglich Bilder von Text enthält. So habe ich im Studium und in der Lehre einige hunderte PDFs gesammelt, die Scans von Büchern enthalten, also im Endeffekt nur Bilder in einer PDF sind. Diese lassen sich naturgemäß nicht durchsuchen, wenn man sie nicht in Text konvertiert. Dies lässt sich wunderbar mit dem Paket OCRmyPDF
durchführen. Es installiert alle notwendigen Programme um Scans oder Fotos aufzubereiten und den Text zu erkennen.
Recoll kann zwar beim indizieren auf das Programm Tesseract zugreifen um Text in Bildern zu erkennen, das Ergebnis wird aber nur im Index gespeichert, nicht in der Quelldatei. Damit ist diese nicht im PDF-Viewer oder mit pdfgrep
durchsuchbar. Außerdem wird der OCR-Prozess jedesmal neu durchlaufen, wenn die Datei neu indiziert werden muss. Daher ist es sinnvoller, die PDF-Dateien ohne Text einmal mittels OCRmyPDF in eine durchsuchbare Version zu überführen und diese dann mit Recoll zu indizieren.
Meine gesammelten PDFs liegen zwar in verschiedenen Verzeichnissen nach Lehrveranstaltungen sortiert vor, allerdings sind einige Dateien bereits durchsuchbar und benötigen kein OCR mehr. Daher nutze ich ein kleines Shell-Skript mit pdfgrep
. Dieses durchsucht die PDF-Datei nach Wörtern und gibt den Dateinamen aus, wenn die PDF weniger als 1000 Wörter enthält. Da auch Bilder-PDFs in der Regel einige Metadaten enthalten, wie z.B. Autor, Titel und Datum, nutze ich die Mindestwortzahl von 1000 um diese Dateien ebenfalls zu finden. Natürlich werde damit auch PDF-Dateien mit kurzen Texten getroffen, aber dies ist ein vertretbarer Kompromiss.
find . -name '*.[Pp][Dd][Ff]' -type f -exec sh -c ' for file do [ "$(pdfgrep -c "\w" "$file")" -lt 1000 ] && printf "%s\n" "$file" done' sh {} + >> PDFFILES.txt
Die Dateiliste wird dann an OCRmypDF verfüttert, dabei nutze ich --force-ocr
um die OCR-Erkennung zu erzwingen, da OCRmyPDF bei einigen gescannten DOkumenten anhand der Metadaten fälschlicherweise davon ausgeht, dass das gesamte Dokument schon als Text vorliegt:
for i in `cat PDFFILES.txt` ; do ocrmypdf --force-ocr $i $i.OCR.pdf ; done for i in `find ./ -iname '*.ocr.pdf'`; do mv $i `echo $i | sed 's/.OCR.pdf//'` ; done
Damit werden dann unter Dateiname.pdf.OCR.pdf die durchsuchbaren PDFs abgelegt. Mit der folgenden Schleife überschreibt man die alten PDFs ohne Text mit den neuen PDFs mit OCR-Text.