Andreas: Lokale Suchmaschine

Beitrag lesen

Hallo!

Wie macht man sowas vielleicht etwas performanter?

Alles, was sie einmal erledigen läßt, sollte man nicht immer wieder tun
(vor allem nicht, während der Besucher darauf warten muß).

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

Definiere "groß".

Wahrscheinlich nicht über 100, da bei größeren Seiten wohl mehr Inhalte aus einer DB kommen, aber mir geht es halt darum, was ist wenn das halt alles in statischen html Seiten oder statischen php-Seiten steht. Als statische PHP-Seite betrachte ich Seiten, wo nur ein Counter oder Änderungsdatum.... steht, keine dynamich erzeugten Daten - also außer counter...

Und bedenke, daß ein einfacher Algorithmus (sequentielles Suchen) Lauf-
zeiten direkt proportional zur durchsuchten Datenmenge haben wird,
während ein Algorithmus unter Verwendung einer Baumstruktur (Daten-
bank-Index etc.) auf logarithmische Suchzeiten (mal Overhead zur Ver-
waltung dieser Datenstruktur) kommen wird. Was von beidem für Dein
Szenario wie gut ist, hängt von Deiner Datenmenge ab.

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?

Kleines Beispiel:
Der zusätzliche Aufwand für die Verwaltung des Indexbaums sei Faktor 7.

Das ist ja egal wenn der User davon nichts mitbekommt, oder? Außerdem kann das mysql z.B. ja automatisch.

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!

  • ich finde auch html-Tags

Nicht, wenn Du sie in einem Vorverarbeitungsschritt bereits entfernst.
Bei statischen Seiten ist das kein Problem; bei dynamischen (PHP) ver-
stehe ich den Sinn der Durchsuchbarkeit nicht so richtig.
Aber wenn der dynamische Anteil sich auf technische Aspekte (z. B.
"last changed" etc.) der Seite beschränkt statt auf Inhalte, ließe sich
eine PHP-Seite wie eine HTML-Seite behandeln.

Das meinte ich. Wie Stefan richtig sagte gibt es ja die PHP-Funktion strip-tags(), die alles zwischen allen <> entfernt, damit auch  zwischen <??>, hatte ich so gar nicht dran gedacht, sorry ;-)

Du kannst HTML-Tags natürlich einfach herauslöschen - das ist leichter.
Du würdest dabei aber darauf verzichten, die Dir in diesen Tags reich-
lich ausgedrückte Semantik Deiner Dokumente zunutze zu machen.
Für die Qualität eines Treffers ist es es doch ein Unterschied, ob der
gesuchte Begriff innerhalb eines <p>, eines <h1> oder gar eines <title>
bzw. <meta> auftritt.

Da hast Du Recht, auf alle Fälle die meta-Angaben, wenn ich die durchgehend mache, wäre das nicht 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

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

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. 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!

aber der erste erscheint mir sehr schwerwiegend.

Eben. Deshalb: Lege Dir eine auf Suchzugriffe optimierte Datenstruktur
an und pflege diese (automatisch) bei jeder Änderung der Quelldokumente.

Bei jeder Änderung ist nicht so einfach, das müßte ich ja immer manuell machen, oder halt täglich per Cronjob immer gucken welche Dateien sich geändet haben und diese Datensätze aktualieren, das wird das sinnvollste und vor allem einfachste sein. Zur Not(bei wichtigen Änderungen) kann man das dann immer noch von Hand anstoßen.

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 ;-)

Zum regulären Ausdruck, sowas wie />(.*?)</  würde das nicht schon
reichen?

Damit würdest Du _einen_ Teil des Dokuments finden, der irgendwo zwi-
schen zwei Tags steht.
Nicht aber alle - dafür müßtest Du mindestens mit einer Schleife durch
das Dokument laufen.

Normalerweise würde in PERL glaube ich ein /g reichen, das geht leider nicht in PHP, dafür läuft obiger Ausdruck verwendet mit preg_match() z.B. automatisch komplett durch und findet so viele Treffer wie vorhanden sind. Wobei ich stattdessen wohl lieber strip_tags() verwende, aber nur am Ende für den Body-Bereich, vorher  brauche ich ja noch die Möglichkeit alles zwischen <meta...> zu extrahieren, mein Versuch:

<?
$html; //Seitenquelltext

$title_array = preg_grep("/<title>(.*?)</title>/",$html);
$meta-desc_array = preg_grep("/<meta name="description" content="(.*?)">/",$html);
$meta-keyw_array = preg_grep("/<meta name="keywords" content="(.*?)">/",$html);
$h1_array = preg_grep("/<h1>(.*?)</h1>/",$html);
$b_array = preg_grep("/<b>(.*?)</b>/",$html);

$title = $title_array[0];
$meta-description = $meta-desc_array[0];
$meta-keywords = $meta-keyw_array[0];
$h1 = implode(" ",$h1_array );
$b = implode(" ",$b_array );
$body = strip_tags($html);
?>

So würde ich jedes Seite halt "zerpflücken", dadurch das die title, meta... Angaben absichtlich im body ein 2. Mal vorkommen, erhalten diese ja automatisch etwas mehr Relevanz bei der MySQL Fulltext-Search.

Was sagst Du dazu?

Schonmal vielen Dank für diese hilfreiche Antwort und

viele Grüße
Andreas