[HowTo] Grösse der search Tabellen verringern (2.0.5)
Eine Anleitung, wie man die Tabellen der phpBB-Suche verkleinern kann und die Suche durch search_stopwords optimiert.
Hinweis: die deutsche Version 2.0.6 von http://www.phpbb.de/download.php sowie das deutsche Sprachpaket von http://prdownloads.sourceforge.net/phpbb/lang_german.zip enthalten bereits die hier erwähnten Dateien search_stopwords.txt und search_synonyms.txt
Überblick- Einleitung
- Erstellen von search_stopwords.txt
- Löschen von search_stopwords.txt Wörtern aus den search Tabellen
- Einleitung
Die Suchfunktion von phpBB benutzt 2 Tabellen: search_wordlist, die einen Eintrag für jedes Wort, das jemals auf dem Board geschrieben wurde, enthält. search_wordmatch, die die Übersicht enthält welcher Beitrag zu welchem Wort aus der search_wordlist passt.
Das ist ein grosser Vorteil für die Schnelligkeit beim Suchen, der Nachteil liegt aber in der Grösse der search Tabellen. Wenn Ihr genug Webspace habt, wird Euch diese Anleitung nicht interessieren. Wenn Ihr jedoch daran interessiert seid, Eure Datenbankgrösse zu reduzieren, dann wird das folgende sicherlich etwas für Euch sein (zumindest ein Anfang). Jedoch benötigt man Kenntnisse, z.B. wie man Queries (sql-Befehle) in der Datenbank ausführt (z.B. mit phpmyadmin).
Mit der folgenden Anleitung konnte ich meine Datenbankgrösse um etwa 15 - 20% reduzieren (ca. 1 MB bei einem 3800 Beiträge umfassenden Board (6.5MB => 5.4 MB)). Euer Ergebnis kann natürlich etwas variieren.
phpBB besitzt bereits die Funktionalität, um ein unnötiges Wachsen der search Tabellen zu verhindern, Beispiel: Es markiert häufig benutzte Wörter als common_word in search_wordlist und stoppt das Einfügen weiterer Übereinstimmungen von diesem Wort in search_wordmatch.
Ein weiteres Feature in phpBB: Es kann (und tut es auch, wenn Englisch die Standardsprache ist) eine Blacklist/Schwarze Liste von Wörter benutzen, wodurch alle Wörter, die in dieser Liste enthalten sind, bei der Suche nicht indiziert werden. Diese Liste ist in einer einfach .txt Datei gespeichert - ein Wort pro Zeile (language/lang_english/search_stopwords.txt).
Mit dieser Anleitung kann man es einstellen, das diese Liste auch benutzt wird.
Desweiteren zeigt ich Euch wie man das meistgenutzte Wort herausfinden kann. Und mit einem kleinen Script, kann man dann alle bisherigen Sucheinträge, die die Wörter von dieser Liste enthalten, entfernen.
- Erstellen von search_stopwords.txt
Um die Liste effektiv zu gestalten, sollte sie natürlich nicht zu lang werden, jedoch derartige Top-Wörter enthalten, z.B. "der, die, das, ich". Um diese Wörter herauszufinden, kann man folgenden Query in der Datenbank (z.B. mit phpmyadmin) ausführen (auf prefix_ achten, hier im Beispiel ist es phpbb_):
Zitat: | SELECT ls.word_id, ls.word_text, COUNT(wm.word_id) as entries FROM `phpbb_search_wordlist` as ls LEFT JOIN `phpbb_search_wordmatch` as wm ON ls.word_id=wm.word_id GROUP BY wm.word_id ORDER BY entries DESC LIMIT 0,50 | Das Ergebnis ist eine Liste von den am meist genutzten Wörter in absteigender Reihenfolge, mit drei Spalten:- word_id - einzigartig für jedes Wort, zeigt die relevanten Einträge in den beiden search Tabellen an.
- word_text - das Wort
- entries - die Anzahl der Einträge in search_wordmatch für dieses Wort.
Als nächstes schaut man sich jeden Eintrag an und entscheidet ob man ihn übernehmen will oder nicht (wodurch ein Suchen nach diesen Wörter unmöglich wird).
Nun speichert man diese Wörter in einer normalen Textdatei ab (pro Zeile ein Wort - ohne id/entries) und benennt die Datei search_stopwords.txt. Anschliessend platziert man sie in folgenden Ordner: language/lang_xxx/ (xxx kennzeichnet die Sprache, die im Adminpanel als Standard eingestellt ist).
Von nun an werden diese Wörter nicht mehr länger für die Suchfunktion indiziert.
Löschen von search_stopwords.txt Wörtern aus den search Tabellen
Nun muss man sämtliche Einträge der Wörter von der Blacklist aus den search Tabellen löschen. (Anschliessend sollten beide Tabellen optimiert werden.) Das folgende ist ein Beispielscript, das genau dies durchführt und wunderbar bei mir funktionierte (ich habe mySQL 3.23 and php 4.1, eventuell benötigt das Script Modifikationen wenn Du andere Vorgaben hast).
Nach dem Ausführen des Script, sollte es vom Server gelöscht werden (auch wenn man damit keinen Schaden anrichten kann).
Code: |
<?php
//***** reduce_my_searchtables_with_stopwords.php ****//
define('IN_PHPBB', true);
$phpbb_root_path = './';
include($phpbb_root_path . 'extension.inc');
include($phpbb_root_path . 'common.'.$phpEx);
include($phpbb_root_path . 'includes/functions_search.'.$phpEx);
// Start session management
$userdata = session_pagestart($user_ip, PAGE_SEARCH);
init_userprefs($userdata);
// End session management
$stopwords_array = file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . "/search_stopwords.txt");
$liste='';
foreach($stopwords_array as $curr_word)
{
$liste .= ( ( $liste != '' ) ? ', ' : '' ) ."'".trim($curr_word)."'";
}
$sql = "SELECT word_id
FROM " . SEARCH_WORD_TABLE . "
WHERE word_text IN ($liste)";
if ( !($result = $db->sql_query($sql)) )
{
message_die(GENERAL_ERROR, 'Could not obtain common word list', '', __LINE__, __FILE__, $sql);
}
$common_word_id = '';
while ( $row = $db->sql_fetchrow($result) )
{
$common_word_id .= ( ( $common_word_id != '' ) ? ', ' : '' ) . $row['word_id'];
}
if ($common_word_id=='') message_die(GENERAL_ERROR,'None of the words in the list are in your search_tables.<br>Note: This could also mean the list is empty ;)');
//echo '>'.trim($curr_word)."<<br>";
//echo $liste .'<br>'. $common_word_id;
//exit;
$sql = "DELETE FROM " . SEARCH_WORD_TABLE . "
WHERE word_id IN ($common_word_id)";
if ( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, 'Could not delete word match entry', '', __LINE__, __FILE__, $sql);
}
$sql = "OPTIMIZE TABLE " . SEARCH_WORD_TABLE;
if ( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, 'Could not optimize', '', __LINE__, __FILE__, $sql);
}
$sql = "DELETE FROM " . SEARCH_MATCH_TABLE . "
WHERE word_id IN ($common_word_id)";
if ( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, 'Could not delete word match entry', '', __LINE__, __FILE__, $sql);
}
$sql = "OPTIMIZE TABLE " . SEARCH_MATCH_TABLE;
if ( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, 'Could not optimize', '', __LINE__, __FILE__, $sql);
}
message_die(GENERAL_MESSAGE,'<b>Done!</b><br><br>The following list-entries have been removed from your searchtables:'.$liste);
//echo $liste .'<br>'. $common_word_id;
?>
|
Ergänzung von itst:
Hier eine deutsche Stopwort-Liste und das passende Skript zum Entfernen aus den Tabellen:
http://www.phpbb.de/diverses/search_stopwords.txt
http://www.phpbb.de/diverses/stop.phps
Mit dem folgenden MOD kann man den Suchindex neu indizieren, was man nach dem Stop-Skript sowie nach jeder Änderung der Stopwortliste machen muss: http://www.phpbb.de/moddb/mod.php?id=10
Hinweis: Vor jeglichen Änderungen an der Datenbank sollte diese mit einem Backup gesichert werden.
|