Michael Schröpl: Lokale Suchmaschine

Beitrag lesen

Hi Andreas,

Ich denke, das es am einfachsten ist, täglich
per Cronjob ein Script laugen zu lassen, welches
die Arbeit erledigt.

Das ist eine Möglichkeit.

Du kannst auch jeweils ein Skript über die Dokumente
laufen lassen, deren Inhalt sich gerade bzw. seit
einem definierten Zeitpunkt geändert hat.

Definiere "groß".
Wahrscheinlich nicht über 100,

Dann hast Du bei der Verwendung des "trivialen"
Ansatzes keine Performance-Probleme zu befürchten.
(Dies wird weiter unten noch von Bedeutung sein.)

Wie gesagt, nicht ganz so viel. Also wie ich das
sehe habe ich entweder die Möglichkeit alle Daten
in eine index-Datei zu schreiben, das ergäbe eine
sequentielle Suche, oder alles in eine Datenbank
zu schreiben, das ergäbe bei gut gewähltem Index
eine rekursiver Suche, oder?

Nicht die Datenbank macht die rekursive Suche aus,
sondern die Art der Abfrage.

Wenn Du ein Dokument lediglich so speicherst, daß
Du dessen gesamten Text als ein Feld der Datenbank
darstellst, hast Du gegenüber der Textdatei nichts
gewonnen.
Stellst Du das Dokument aber so dar, daß Du jedes
einzelne Wort in dieser Tabelle speicherst, dann
kannst Du Worte über den entsprechenden Index in
logarithmischer Zeit finden. Das bedeutet aller-
dings erst mal, einen Wort-Indexer schreiben zu
müssen (oder den zu verwenden, den die Datenbank
schon hat, etwa mySQL-FULLTEXT), und es bedeutet
auch, auf eine Phrasensuche (mehrere Worte im di-
rekten Kontext) verzichten zu müssen.

Der zusätzliche Aufwand für die Verwaltung des
Indexbaums sei Faktor 7.
Das ist ja egal wenn der User davon nichts
mitbekommt, oder?

Das _bekommt_ der Benutzer mit.
Es kann allerdings sein, daß dieser Faktor 7 deshalb
nicht auffällt, weil er nur bei Datenmengen stört,
die so klein sind, daß der Grundaufwand (CGI-Anbindung
etc.) höher ist als die eigentliche Suche.

Außerdem kann das mysql z.B. ja automatisch.

Das ändert nichts daran, daß es die Laufzeit erhöht.
Indexadressierung ist nicht kostenlos - es gibt einen
breakeven-Punkt, und den wollte ich Dir vorführen.

Faktor 100 schneller sein. Bei wenigen hundert
Datensätzen lohnt sich der (erheblich höhere)
Implementierungsaufwand noch nicht
Aber wo ist da der höhere Aufwand? Finde es fast
leichter die Daten in eine DB zu schreiben, als
mir selber eine Struktur für eine index-Datei zu
überlegene, die ich danach vergleichbar einfach
durchsuchen kann!

Du mußt Dir die Struktur in jedem Fall überlegen -
und Du tust es weiter unten ja auch.

Ob das Ergebnis dann eine CSV-Daten oder eine SQL-
Tabelle ist, das ist relativ egal - aber ob Du
einfach eine Datei aufmachst oder eine Datenbank-
schnittstelle per SQL ansteuern mußt, das ist für
jemand, der in SQL nicht fit ist, sehr wohl ein
Unterschied.

schlecht. Ich stelle mir das so vor, ich mache
eine DB-Tabelle die wie folgt aussieht:
ID
URL
title
alle <h1>
meta-keywords
meta-description
body(nach strip-tags())
timestamp

Genau das meinte ich. Zu diesem Zeitpunkt ist die
Realisierungsform (Tabelle oder Datei) noch völlig
offen - es geht erst einmal darum, die Semantik
Deiner Suchmaschine zu definieren: Welche Abfragen
sind überhaupt möglich, und welche Informationen
stehen für die Definition einer Bewertungsfunktion
zur Sortierung der Treffer zur Verfügung.
Hier machst Du Deine Datenmodellierung.

Jetzt über alle Spalten außer ID, URL und timestamp
einen Fulltext-Index, und dann in allen diesen
Spalten nach einem Suchbegriff suchen.

Für Wortsuche prima ... für Phrasensuche nicht.
Das ist ein wesentlicher Teil der Funktionalität,
sich für bzw. gegen Phrasensuche zu entscheiden.

MySQL gibt dann ja sogar selbst die Relevanz des
Begriffes zurück, nur wahrscheinlich nicht unter
Beachtung der von Dir angesprochenen und damit
beabsichtigten Semantik.

Die kannst Du aber als Gewicht drauf multiplizieren.

Aber um das zu bekommen
bräuchte ich ja ein Abfrage pro Spalte, und müßte
das danach noch auswerten, vor allem habe ich dann
keine Ahnung was ich wie gewichten soll, im
Verhältnis jetzt zur mySQL Relevanz!

Das ist in der Tat ein Problem. Aber Du mußt ja nicht
die Relevanzfunktion von mySQL verwenden. Du mußt auch
nicht deren FULLTEXT verwenden - ein Wort-Indexer ist
schnell geschrieben, und der könnte die Relevanz eines
Wortes für ein Dokument unter Berücksichtigung _aller_
Spalten bereits vor dem Einfügen dieses Wortes in die
Datenbank berechnen. Du hättest also eine Tabelle mit

CREATE TABLE fulltext AS
  search_word      <irgend ein char-Typ>
  search_quality   <integer>
  document_id      <primary key der anderen Tabelle>

und würdest suchen mit

SELECT document_id, search_quality
   FROM fulltext
  WHERE search_word = <suchbegriff>
  ORDER BY search_quality DESC;

oder so ähnlich.

Redundanz ist zwar in vielen Fällen "böse", aber
in diesem Fall der Schlüssel zu Performance.
Ich hoffe Du meintest Das so ähnlich wie ich jetzt
geschrieben habe ;-)

Ich denke schon. Die Such-Datenbank enthält natürlich
dieselben Inhalte wie die eigentlichen Dokumente,
aber eben auf eine andere Art des Zugriffs optimiert.

Viele Grüße
      Michael