Montag, 16. Februar 2009

Stopwörter und Stoplisten: Unwichtige Wörter ... (wirklich unwichtig? ...)

Bekanntlich unterstützt Oracle TEXT Stopwortlisten. Wird ein Wort als Stopwort deklariert, wird es von Oracle TEXT völlig ignoriert - Stopwörter werden nicht in den Index aufgenommen und bei Abfragen insofern nicht berücksichtigt. Bei Abfragen auf einzelne Wörter (Tokens) ist das relativ klar; eine Suche nach "und" wäre auch sinnlos. Stopwörter haben allerdings einen Einfluß auf die Phrasensuche - sie passen auf jedes Wort. Sucht man beispielsweise nach der Phrase "Radio und Fernseher", so sucht Oracle TEXT (wenn die Stopwortliste aktiv ist und bspw. die Wörter "und", "oder" und "unter" enthält) im Index nach "Radio {?} Fernseher". Gefunden würden auch Dokumente, in denen die Phrase Radio oder Fernseher oder Radio im Fernseher vorkommt. Wenn solcherlei Effekte nicht gewünscht sind, muss man die Stopwortliste abschalten.
Aber welche Wörter sind überhaupt Stopwörter ...? Dazu schaut man erstmal nach, welche Stopwortlisten es überhaupt gibt - die Stopwörter sind in Listen organisiert ...
SQL> select * from ctx_stoplists

SPL_OWN SPL_NAME                   SPL_COUNT SPL_TYPE
------- ------------------------- ---------- ----------------
CTXSYS  DEFAULT_STOPLIST                 235 BASIC_STOPLIST
WKSYS   WK_STOPLIST                       76 BASIC_STOPLIST
CTXSYS  EMPTY_STOPLIST                     0 BASIC_STOPLIST
CTXSYS  EXTENDED_STOPLIST                  0 BASIC_STOPLIST
TM      SWL_BRANCHEN                      10 BASIC_STOPLIST

5 Zeilen ausgewählt.
Die CTXSYS.DEFAULT_STOPLIST ist eine Standardliste für die Sprache, mit der die Datenbank aufgesetzt wurde - Hierzulande ist das im Normalfall Deutsch. Und auch da kann man reingucken ...
SQL> select spw_type, SPW_WORD from ctx_stopwords where SPW_STOPLIST='DEFAULT_STOPLIST'

SPW_TYPE   SPW_WORD
---------- ------------------------------
STOP_WORD  Ihnen
STOP_WORD  Ihre
STOP_WORD  Ihrem
STOP_WORD  Ihren
STOP_WORD  Ihrer
STOP_WORD  Ihres
:          :
Enthalten sind also Bindewörter, Präpositionen, Artikel und ähnliche Wörter; also alles, was typischerweise in jedem Dokument vorkommt und daher ignoriert werden kann.
Die Skripte, mit denen diese Defaults erzeugt werden befinden sich in $ORACLE_HOME/ctx/admin/defaults. So spielt das darin vorhandene Skript drdefd.sql die deutsche Standard-Stopliste ein; drdefus.sql entsprechend die US-amerikanische. Wenn in der Datenbank also eine englische Stopliste enthalten ist (weil beim Aufsetzen alles mit englischer Sprache gelaufen ist), so lässt sich das (als User CTXSYS) einfach ändern ...
SQL> start ?/ctx/admin/defaults/dr0defdp.sql
SQL> start ?/ctx/admin/defaults/drdefd.sql
Stoplisten sind wie alle anderen Datenbankobjekte einem Schema zugeordnet; das Schema CTXSYS enthält die Standardlisten. Eigene Stoplisten sollten stets auch ins eigene Datenbankschema (und nicht in CTXSYS) abgelegt werden. Die Skripte können auch als Basis für Erweiterungen verwendet werden. Möchte man mit Stopwortlisten arbeiten, kann es durchaus sinnvoll sein, diese durch branchentypische Fachbegriffe zu erweitern. Die Standardlisten enthalten nur solche Wörter, von denen Oracle sicher ist, dass sie in nahezu jedem Dokument vorkommen. Es mag nun branchenspezifische Wörter geben, die man hinzufügen möchte: In einer Bank könnten dies Begriffe wie "Bank", "Betrag", "Konto" oder ähnliche sein. Beim Festlegen solcher Begriffe sollte man aber stets darauf achten, dass die Stopwörter (wie eingangs erwähnt) auch bei der Phrasensuche ignoriert werden.
begin
  ctx_ddl.add_stopword(
    'MY_STOPLIST',
    'bank'
  );
end;
Ein Index mit dieser Stopliste wird dann so gebaut:
create index idx_volltext on dokument_tab (spalte)
indextype is ctxsys.context
parameters ('stoplist my_stoplist')
/
Diese Syntax hat keinen Einfluß auf schon bestehende Volltextindizes. Möchte man auf einem schon erzeugten Index ein (zusätzliches) Stopwort einrichten, gibt es eine spezielle Syntax:
  alter index idx_volltext add stopword bank;
Der Index wird dadurch nicht neu erzeugt, auch werden diese Wörter (so sie vorhanden sind) nicht aus dem Index gelöscht. Das neue Stopwort wird einfach nur in die Metadaten eingetragen, so dass es bei künftigen Abfragen und neuen Dokumenten wirken kann. Diese Operation kann es logischerweise nicht für das Entfernen von Stopwörtern geben; denn dazu müssen diese ja neu in den Index aufgenommen werden. Möchte man Stopwörter aus einem Index entfernen, so muss dieser neu gebaut werden.
begin
  ctx_ddl.remove_stopword( 'MY_STOPLIST', 'bank');
  ctx_ddl.remove_stopword( 'MY_STOPLIST', '{...}');
end;
/

ALTER INDEX idx_volltext REBUILD PARAMETERS('replace stoplist MY_STOPLIST')
/
Mehr zum Thema findet sich in der Oracle-Dokumentation: TEXT Application Developers' Guide und TEXT Reference.

Beliebte Postings