Wir nutzen im Beispiel die Tabelle TEXTTABELLE aus dem Blog und definieren zusätzlich die Präferenz für Mixed Case.
execute ctx_ddl.drop_preference('MY_LEXER');
begin
ctx_ddl.create_preference(
preference_name => 'MY_LEXER',
object_name => 'BASIC_LEXER');
-- Mixed Case abschalten
ctx_ddl.set_attribute(
preference_name => 'MY_LEXER',
attribute_name => 'MIXED_CASE',
attribute_value => 'NO');
end;
/
Danach setzen wir explizit die BASIC_WORDLIST auf den Wert 1, um einen Fehler auszulösen.
execute ctx_ddl.drop_preference('my_wordlist');
BEGIN
ctx_ddl.create_preference('my_wordlist', 'BASIC_WORDLIST');
ctx_ddl.set_attribute('my_wordlist', 'WILDCARD_MAXTERMS', 1);
END;
/
Nun wird der Index angelegt ...
CREATE INDEX idx_text ON texttabelle (dokument)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('WORDLIST my_wordlist LEXER MY_LEXER')
/
Bei der folgenden Abfrage erhalten wir nun einen Fehler, da eigentlich mehr als ein Ergebnis zu erwarten ist.
SQL> SELECT * FROM texttabelle WHERE contains (dokument,'%gewinn%')>0;
SELECT * FROM texttabelle WHERE contains (dokument,'%gewinn%')>0
*
FEHLER in Zeile 1:
ORA-29902: Fehler bei der Ausführung von Routine ODCIIndexStart()
ORA-20000: Oracle Text error:
DRG-51030: wildcard query expansion resulted in too many terms
Verifizieren wir das Ganze nun mit der Token-Tabelle, um die Ergebnisbegriffe einzusehen.
SQL> SELECT token_text FROM dr$idx_text$i WHERE upper(token_text) like '%GEWINN%';
TOKEN_TEXT
----------------------------------------------------------------
GEWINNT
GEWINNZUWACHS
Ändern wir also in der Wordlist das WILDCARD_MAXTERMS Attribut auf den Wert 20000. Dies ist übrigens in 11g der Default-Wert.
execute ctd_ddl.drop_preference('my_wordlist');
BEGIN
ctx_ddl.create_preference ('my_wordlist', 'BASIC_WORDLIST');
ctx_ddl.set_attribute ('my_wordlist', 'WILDCARD_MAXTERMS', 20000);
END;
/
Passen wir im nächsten Schritt die Wordlist des Index an. Dies könnte Online mit Unterstützung des Shadow Index durchgeführt (siehe Blog) werden.
execute ctx_ddl.recreate_index_online('IDX_TEXT','REPLACE WORDLIST my_wordlist');
Nun erhalten wir das erwartete Ergebnis.
SQL> SELECT * FROM texttabelle WHERE contains (dokument,'%gewinn%')>0
ID DOKUMENT
---------- --------------------------------------------------
2 A-Partei gewinnt Wahl in Hansestadt
4 Wirtschaft: Erneuter Gewinnzuwachs in diesem Jahr
Je nach Release der Datenbank gibt es unterschiedliche Default-Werte für das WILDCARD_MAXTERMS Attribut. Prüfen lässt sich dies mit folgender Abfrage:
SQL> SELECT oat_default, oat_min, oat_max
FROM ctx_object_attributes
WHERE oat_attribute LIKE '%MAXTERM%'
OAT_DEFAULT OAT_MIN OAT_MAX
-------------------- ---------- ----------------------------------------
20000 0 50000
Der aktuelle Wert lässt sich über folgende Abfrage ermitteln:
SQL> SELECT * FROM ctx_user_preference_values;
PRV_PREFERENCE PRV_ATTRIBUTE PRV_VALUE
------------------------------ ------------------------------ ----------
MY_LEXER MIXED_CASE NO
MY_WORDLIST WILDCARD_MAXTERMS 50000
Eine Anmerkung zum Schluss: Eine Erhöhung von WILDCARD_MAXTERMS muss nicht die optimale Lösung sein. Manchmal hilft eine Erweiterung der Stoppliste oder eine Anpassung der Auswahlliste innerhalb einer Webapplikation um den Anforderungen zu genügen.