Vor einiger Zeit hatten wir ein Blog Posting zum Thema "Fuzzy-Suche". Darin könnt Ihr nachlesen, wie eine Ähnlichkeitssuche mit Oracle TEXT funktioniert und wie Ihr sie parametrisieren könnt.
Wie beschrieben, führt Oracle TEXT eine sog. Termexpansion durch. Die Suchabfrage wird also zunächst um
Tokens aus dem Textindex, die dem gesuchten Begriff ähnlich sind, erweitert und anschließend wird
mit dieser Token-Liste eine OR-Suche durchgeführt. Die Parameter des FUZZY-Operators steuern diese
Termexpansion.
Nun wäre es schön, wenn man sich ansehen könnte, was er da tut - welche Tokens also in die Liste
mit aufgenommen werden. Und genau das ist mit der Prozedur CTX_QUERY.EXPLAIN möglich (übrigens nicht nur für die Fuzzy-Suche, sondern für alle TEXT-Abfragen). Die EXPLAIN-Funktion generiert eine Art "Ausführungsplan" für den Oracle TEXT Index.
Zunächst benötigen wir eine EXPLAIN TABLE - dort schreibt die Prozedur die Erklärungen
zu einer Textquery hinein. In der Oracle-Dokumentation "Text Reference" findet Ihr Erlärungen
zu Aufbau und Inhalt. Erzeugt wird sie mit diesem CREATE TABLE-Kommando:
create table meine_explain_tabelle( explain_id varchar2(30), id number, parent_id number, operation varchar2(30), options varchar2(30), object_name varchar2(64), position number, cardinality number );
Wenn Ihr die Tabelle erstellt habt, könnt Ihr euch eine Textquery beschreiben lassen.
begin ctx_query.explain( index_name => 'IDX_DOKUMENTE', text_query => '?sptial or geodaten', explain_table => 'MEINE_EXPLAIN_TABELLE' ); end; /
Anschließend stehen die Erklärungen in der erzeugten EXPLAIN-Tabelle. Wichtig ist der Parameter
SHARELEVEL, der in diesem Aufruf nicht angegeben wurde. Der Default ist "0" (Null), was
bedeutet, dass die Tabelle vorher leergeräumt wurd (TRUNCATE). Wenn Ihr EXPLAIN-Ergebnisse
aufheben möchtet, setzt den Parameter auf "1" - zusätzlich benötigt Ihr dann eine EXPLAIN_ID,
damit Ihr die Erklärungen später wiederfinden könnt.
Die Einträge in der Tabelle sind hierarchisch organisiert - am besten fragt Ihr sie
daher mit einem START WITH - CONNECT BY wie folgt ab.
select lpad(' ',level * 2)|| to_char(id, '99') id, operation, options, object_name, position from meine_explain_tabelle start with parent_id =0 connect by parent_id = prior id /
Das Ergebnis sieht dann etwa so aus
ID OPERATION OPTIONS OBJECT_NAME POSITION ---------- --------------- ---------- --------------- -------- 1 OR 1 2 EQUIVALENCE (?) sptial 1 3 WORD Spatial 1 4 WORD special 2 5 WORD Special 3 6 WORD Spezial 4 7 WORD Spiel 5 8 WORD spielt 6 9 WORD spielte 7 10 WORD Spitze 8 11 WORD sptial 9 12 WORD geodaten 2
Man erkennt sehr schön die ähnlichen Worte, die Oracle TEXT in die Abfrage eingebunden hat; man könnte nun, wie im Blog Posting zur "Fuzzy-Suche" beschrieben, das Schlüsselwort FUZZY nutzen und parametrisieren: Wie versuchen also die Abfrage FUZZY(sptial,70,5) or geodaten. Die in Frage kommenden Wörter müssen sich also ähnlicher sein (Wert "70" im Gegensatz zum Default von "60") und es werden maximal fünf Wörter in die Termexpansion einbezogen. Das Ergebnis ...
ID OPERATION OPTIONS OBJECT_NAME POSITION ---------- --------------- ---------- --------------- -------- 1 OR 1 2 EQUIVALENCE (?) sptial 1 3 WORD Spatial 1 4 WORD sptial 2 5 WORD geodaten 2
Und wenn man nach "Spatial" im Zusammenhang mit "Geodaten" sucht, erkennt man sofort, dass
diese Suche viel zielgenauer ist. Gerade wenn es um das Spielen mit den Parametern für
eine FUZZY-Suche geht, ist die EXPLAIN-Funktion eine wertvolle Hilfe.
Viel Spaß beim Ausprobieren!