Montag, 15. Juli 2013

Oracle TEXT in Oracle12c: Neues Feature 'Pattern Stopclass'

Heute festgestellt, dass das letzte Blog Posting schon fast 3 Monate zurückliegt. Nun wird es aber Zeit: Das neue Datenbankrelease Oracle12c bringt auch im Bereich Oracle TEXT einige neue Features mit sich - diese werden wir nach und nach in diesem Blog besprechen. Heute geht es um die neue Möglichkeit, eine Stopwortliste nicht nur mit einzelnen Wörtern, sondern mit Stop-Patterns zu versehen. Hierauf haben viele sicherlich schon lange gewartet. Ein Beispiel: Wir erzeugen eine Tabelle und füllen diese mit ein paar "Wörtern" ...
create table tab_stopclasstest (
  textcol  varchar2(200)
)
/

insert into tab_stopclasstest values ('200');
insert into tab_stopclasstest values ('100');
insert into tab_stopclasstest values ('99');
insert into tab_stopclasstest values ('Oracle TEXT');
insert into tab_stopclasstest values ('A100');
insert into tab_stopclasstest values ('01.09.2012');
Wenn es nun an die Definition der Stopwörter geht, so konnte man bislang mit CTX_DDL.CREATE_STOPLIST eine Stopliste erzeugen und mit CTX_DDL.ADD_STOPWORD die Wörter ("Oracle") hinzufügen.

begin
  ctx_ddl.create_stoplist(
    stoplist_name => 'NEUE_STOPLISTE'
  );
  ctx_ddl.add_stopword ('NEUE_STOPLISTE', 'Oracle');
  ctx_ddl.add_stopclass('NEUE_STOPLISTE', 'NUMBERS');
end;
/
Aber genau dabei beginnt in vielen Fällen das Problem: Denn wenn Zahlen nicht indiziert werden sollen, ist es nahezu unmöglich, im Vorfeld alle möglichen Varianten als Stopwörter zu bestimmen. Die Stopclasses machen nun genau das möglich (übrigens kann man die Stopklasse NUMBERS schon in Oracle 11.2 verwenden) - aber dort eben nicht mehr. Anders in Oracle12c ...
begin
  ctx_ddl.create_stoplist(
    stoplist_name => 'NEUE_STOPLISTE'
  );
  ctx_ddl.add_stopword ('NEUE_STOPLISTE', 'Oracle');
  ctx_ddl.add_stopclass('NEUE_STOPLISTE', 'NUMBERS');
  ctx_ddl.add_stopclass('NEUE_STOPLISTE', 'KLASSE_1','[A-Z]\d+');
end;
/
CTX_DDL.ADD_STOPCLASS nimmt drei Parameter entgegen. Der erste ist, wie schon bei ADD_STOPWORD, der Name der Stopliste. Danach kommt die "Stopklasse" - Oracle bringt eine vordefinierte Klasse mit: NUMBERS, die, wie gesagt, schon in 11.2 vorhanden ist. Ab Oracle 12.1 kann man aber auch einen anderen Namen eintragen - und dann braucht es noch den dritten Parameter: Dort wird ein regulärer Ausdruck hinterlegt, der die zu ignorierenden Wörter erfasst. In obigem Beispiel wäre das genau ein Buchstabe, gefolgt von mindestens einer Zahl. Legt man, basierend auf dieser Stopliste einen Index auf die obige Tabelle an, so wird dieser nur ein einziges Token enthalten: TEXT.
create index ft_stopclasstest on tab_stopclasstest (textcol)
indextype is ctxsys.context 
parameters ('stoplist neue_stopliste')
/

select token_text from dr$ft_stopclasstest$i
/

TOKEN_TEXT
-----------------------------------------
TEXT
Viel Spaß beim Ausprobieren.

Kommentare:

student hat gesagt…

hallo,

die frage ist nicht explizit zum beitrag, sondern bezieht sich auf mehrere.

kann man eine selektion nach anderen tabellenspalten vornehmen als der aus dem index?

beispiel: eine tabelle mit zwei spalten (id, text). es sollen alle wörter (ohne stopwörter) einer bestimmten id angezeigt werden.
ergebnis: 1234 | bayern gewinnt pokal

nach dem indextype ctxsys.context (token_text)kann keine selektion nach der id mehr vorgenommen werden. nimmt man zwei felder in den index auf, kommt einer fehlermeldung bzgl des domain index. "funktionen" wie section oder multi_colum haben liefern nicht das gewünschte ergebnis - zumindestens nicht bei mir :-)

vg student

Carsten Czarski hat gesagt…

Hallo "student",

hier wäre der "Multicolumn Datastore" schon genau die richtige Technologie. Dazu gibt es auch ein eigenes Blog-Posting: Mehrere Tabellenspalten indizieren: MULTICOLUMN_DATASTORE. Wichtig ist, dass man bei der Abfrage die richtigen WITHIN-Klauseln verwendet - auch das ist im Blog-Posting beschrieben ...

Hilft dies weiter?

Beste Grüße

Carsten Czarski

Beliebte Postings