Posts mit dem Label format column werden angezeigt. Alle Posts anzeigen
Posts mit dem Label format column werden angezeigt. Alle Posts anzeigen

Montag, 10. Oktober 2011

Einzelne Zeilen vom Index ausnehmen - Parameter "FORMAT COLUMN"

Heute geht es um einen eher unscheinbaren Parameter beim Erstellen eines Oracle TEXT Index:
Mit FORMAT COLUMN kann zum einen der Filter für Binärdokumente gesteuert werden - darüber hinaus
kann man damit aber auch festlegen, ob das Dokument überhaupt indiziert werden soll. Und das geht so - wir fangen mit einer einfachen Tabelle an:
create table test(
  id     number(10) not null,
  text   varchar2(4000) not null,
  format varchar2(10) not null,
  constraint pk_test primary key (id),
  constraint ck_format check (format in ('TEXT','BINARY','IGNORE'))
)
/

insert into test values (1, 'Dieses Dokument wird indiziert.', 'TEXT')
/
insert into test values (2, 'Hierfür stehen keine Einträge im Textindex', 'IGNORE')
/
Die Indexerstellung funktioniert wie immer - nur, dass der Parameter FORMAT_COLUMN mitgegeben wird.
create index ft_test on test (text)
indextype is ctxsys.context
parameters ('format column format')
/
Danach schauen wir in die $I-Tabelle - dort stehen in der Tat nur Tokens für das erste
Dokument - die Spalte FORMAT enthält hier "TEXT".
SQL> select token_text from dr$ft_test$i;

TOKEN_TEXT
------------------------------------------
DIESES
DOKUMENT
INDIZIERT
WIRD

4 Zeilen ausgewählt.
Aber was passiert, wenn man die Spalte FORMAT ändert - angenommen, wir ändern den Inhalt
für das zweite Dokument von IGNORE in TEXT ...
SQL> update test set format = 'TEXT' where id = 2
/

1 Zeile aktualisiert.
Wenn man nun in der Dictionary View CTX_USER_PENDING nachsieht, ändert sich diese
(obwohl mit der Spalte FORMAT eine "index-relevante" Spalte geändert wurde, nicht. Ein CTX_DDL.SYNC_INDEX
bewirkt also ebenfalls nichts. Man muss
also entweder im Update-Kommando selbst oder mit einem Trigger sicherstellen, dass bei einer
Änderung der Spalte FORMAT auch die Indexspalte selbst "angefasst" wird - das könnte so
aussehen ...
create or replace trigger tr_upd_format
before update of format on test
for each row
begin
  if :old.format != :new.format then 
    :new.text := :old.text;
  end if;
end;
/
Von nun an wirkt eine Änderung an der Spalte FORMAT wie eine Änderung am Dokument - nach der
Index-Synchronisierung ist das Dokument indiziert bzw. aus dem Index entfernt (je nachdem, wie
die Spalte FORMAT gesetzt wurde).
SQL> update test set format = 'IGNORE' where id = 1; 

1 Zeile wurde aktualisiert.

SQL> update test set format = 'TEXT' where id = 2; 

1 Zeile wurde aktualisiert.

SQL> select pnd_rowid from ctx_user_pending; 

PND_ROWID
------------------------------ 
AAAmVGAAFAAAMWTAAA
AAAmVGAAFAAAMWTAAB

2 Zeilen ausgewählt.

SQL> exec ctx_ddl.sync_index('FT_TEST'); 

PL/SQL-Prozedur erfolgreich abgeschlossen.

SQL> exec ctx_ddl.optimize_index('FT_TEST', ctx_ddl.optlevel_full); 

PL/SQL-Prozedur erfolgreich abgeschlossen.

SQL> select token_text from dr$ft_test$i; 

TOKEN_TEXT
----------------------------------------------------------------
EINTRÄGE
HIERFÜR
IM
KEINE
STEHEN
TEXTINDEX

6 Zeilen ausgewählt.

Beliebte Postings