
13 August 2009, 16:45 von
klaus_b1530 mal gelesen.Thesauri finden ihre Verwendung in den verschiedensten Einsatzgebieten. Vom einfachen Wörterbuch über die Unterstützung einer Volltextsuche bis hin zu polyhierarchischen Relationen in komplexen Dokumentationen.
Ich bin allerdings nur an einer Lösung zur Implementierung von Thesaurus-Feature in einer Volltextsuche interessiert. Bei der Verwendung eines Thesaurus in einer Suche wird er meist für zwei Aufgaben verwendet: der Erweiterung und Ersetzung von Suchbegriffen.
Die Erweiterung von Suchbegriffen erscheint mir wesentlich Sinnvoller als das ersetzen von einzelnen Suchwörtern. Vielleicht sehe ich das nur etwas zu eng, aber für mein Empfinden hat das Ersetzen von Suchwörtern etwas von Zensur.
Beim erweitern von Suchbegriffen geht es im wesentlichen um die Verwendung von Synonymen zu einem bestimmten Wort. Gibt ein Benutzer einer Webseite z.B.: JS ein, so soll auch automatisch nach JScript, JavaScript und Java Script gesucht werden. Damit die jeweilige Suche diese Erweiterung auch bewerkstelligen kann, muss die Thesaurus-Funktionalität irgendwie zur Verfügung gestellt werden.
Als erstes müssen die Synonyme eines bestimmten Worts irgendwo hierarchisch zusammengefasst werden. Als einfachste Lösung habe ich mich hier für folgende XML-Datei entschieden:
<?xml version="1.0" encoding="utf-8" ?>
<thesaurus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Thesaurus.xsd">
<extension>
<syn>JS</syn>
<syn>JScript</syn>
<syn>JavaScript</syn>
<syn>Java Script</syn>
</extension>
<extension>
<syn>MS</syn>
<syn>Microsoft</syn>
</extension>
<extension>
<syn>VB</syn>
<syn>Visual Basic</syn>
</extension>
</thesaurus>Wie im obigen Listing zu sehen, ist das Schema der XML-Datei sehr einfach aufgebaut.
Jede Erweiterung enthält für jedes mögliche Synonym einen eigenen Kind-Knoten. Falls es später einmal nötig sein sollte auch Ersetzungen zu unterstützen, kann das sehr einfach “nachgerüstet” werden.
Um die Datenstruktur in Objekten abzubilden, habe ich mir folgende Lösung überlegt:
- Zur Abbildung eines Knoten <extension> verwende ich eine Klasse, die alle Synonyme in einer Aufzählung vorhält.
- Synonyme müssen nur hinzugefügt werden können.
- Es muss überprüfbar sein, ob ein bestimmtes Synonym bereits in der Instanz enthalten ist.
- Alle Klassen mit ihren enthaltenen Synonymen werden in einer Aufzählung gesammelt die den Thesaurus darstellt.
- Jedes Synonym muss im Thesaurus einzigartig sein.
- Alle in der Aufzählung enthaltenen Synonyme sind über einen Index jederzeit abrufbar.
- Jeder der Knoten <extension> ist über jeden seiner enthaltenen Synonyme als ganzer Knoten abrufbar.
Entstanden ist aus diesen Vorgaben folgendes Konstrukt:

Da die Thesaurus-Funktionalität nicht für eine Verwendung außerhalb der Suche vorgesehen ist, sind die öffentlichen Methoden auf die Abfrage eines bestimmten Synonym und die Rückgabe einer Instanz der Klasse ThesaurusExtension begrenzt.
Um das laden der Thesaurus-Datei und die Abbildung des Inhalts kümmert sich komplett die Klasse Thesaurus. Sie reagiert ebenfalls auf Änderungen an der Thesaurus-Datei und erstellt das Objekt-Abbild derselben gegebenenfalls neu.
Dementsprechend Einfach ist die Verwendung dieses Thesaurus. Es braucht nur geprüft zu werden ob ein bestimmtes Suchwort, im oben genannten Beispiel JS, im Thesaurus enthalten ist. Wird true zurückgegeben, kann mit der Methode Find die entsprechende Instanz der Klasse ThesaurusExtension abgefragt werden. Natürlich wird auch bei der Abfrage nach anderen Synonymen der Instanz, etwa JScript oder JavaScript, ebenfalls diese Instanz zurückgegeben. In der Eigenschaft Synonyms der Instanz befinden sich alle dem Suchwort entsprechenden Synonyme und können den Suchwörtern hinzugefügt werden.
// Liste für Synonyme erzeugen
List<string> expanded = new List<string>();
// nach Synonymen suchen
foreach (var word in searchTerms)
{
// wenn der Thesaurus das Suchwort enthält
if (this.thesaurus.Contains(word))
{
// durch die Synonyme iterieren
foreach(var entry in thesaurus.Find(word).Synonyms)
{
// wenn das Synonym nicht gleich
// dem Suchwort ist
if (!word.Equals(entry,
StringComparison.OrdinalIgnoreCase))
{
// als erweiterter Suchbegriff hinzufügenexpanded.Add(entry);
}
}
}
}Da der Thesaurus lediglich eine Auflistung von Objekten darstellt, kann er, wie bereits weiter oben erwähnt, einfach erweitert werden. Sollten einmal Ersetzungen nötig sein, können diese einfach implementiert werden ohne die Kompatibilität mit der jetzigen Version zu gefährden.
Die vorgestellte Lösung stellt lediglich ein sehr einfaches Modell eines Thesaurus dar. Zudem ist diese Lösung auf die Verwendung in einer Suche zugeschnitten.
Technorati-Tags:
c# |
searching |
thesaurusWenn ihnen der Artikel gefallen hat oder er für sie hilfreich war, bitte "kicken" sie ihn.
