Mit der neuen Oracle Database 12c Version sind einige interessante neue Features im Oracle Text Umfeld implementiert worden. Nach und nach wollen wir diese in unseren deutschsprachigen Postings thematisieren.
Wer jetzt allerdings schon einen Überblick über alle neuen Text Features erhalten möchte, kann entweder im
Oracle Text Application Developer's Guide 12c Release 1 (12.1) im Abschnitt New Features recherchieren oder sich über das neue Whitepaper New Features in Oracle Text with Oracle Database12c informieren.
Viel Spaß dabei!
Montag, 26. August 2013
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.
Donnerstag, 18. April 2013
Indexstatistiken (INDEX_STATS) im XML-Format: Oracle TEXT Management einfach automatisieren!
Heute geht es um Statistiken für einen Oracle TEXT Index - vor einiger Zeit gab es
dazu schon mal ein Posting - heute soll es darum gehen, wie man
diese Statistiken so zur Verfügung stellt, dass man mit Reporting- oder Management-Tools
einfach darauf zugreifen oder diese zur Automatisierung von Aufgaben verwenden kann.
Indexstatistiken kann man mit
CTX_REPORT.INDEX_STATS abrufen. In nahezu allen Beispielen
(so auch im erwähnten Blog-Posting) werden die Statistiken als Textausgabe erzeugt - in etwa wie folgt ...
===========================================================================
STATISTICS FOR "TESTIT"."IDX_TEXT"
===========================================================================
indexed documents: 10
allocated docids: 10
$I rows: 56
---------------------------------------------------------------------------
TOKEN STATISTICS
---------------------------------------------------------------------------
:
Dieses Format ist zwar gut lesbar, zur Automatisierung jedoch völlig ungeeignet. Allerdings
bietet Oracle TEXT noch eine andere Variante zur Ausgabe der Statistiken an: XML - und
das geht wie folgt.
DROP TABLE ausgabe
/
CREATE TABLE ausgabe (
index_name varchar2(200),
zeitstempel date,
resultat xmltype
)
xmltype column resultat store as binary xml
/
declare
ergebnis clob := null;
begin
ctx_report.index_stats(
index_name => 'IDX_TEXT',
report => ergebnis,
report_format => ctx_report.fmt_xml,
stat_type => null
);
insert into ausgabe values ('IDX_TEXT', sysdate, xmltype(ergebnis));
dbms_lob.freetemporary(ergebnis);
end;
/
set long 32000
set head off
set pagesize 10000
SELECT * FROM ausgabe
/
Das generierte Format sieht nun wie folgt aus ...
<CTXREPORT>
<INDEX_STATS>
<STAT_INDEX_NAME>"TESTIT"."IDX_TEXT"</STAT_INDEX_NAME>
<STAT_INDEX_STATS>
<STAT_STATISTIC NAME="indexed documents">10</STAT_STATISTIC>
<STAT_STATISTIC NAME="allocated docids">10</STAT_STATISTIC>
<STAT_STATISTIC NAME="$I rows">56</STAT_STATISTIC>
:
Bei großen Indizes braucht der Aufruf von INDEX_STATS sehr lange - hier ist es sicher sinnvoll,
mit Hilfe von
DBMS_SCHEDULER einen Job zu erzeugen, welcher die Statistiken
regelmäßig (bspw. über Nacht) aktualisiert. Das Interessante am XML-Format ist nun,
dass es sich maschinell auswerten lässt. Dazu nutzen wir die XML-Funktionen in der
Oracle-Datenbank und erstellen eine (relationale) View auf die XML-Ausgabe von
CTX_REPORT.INDEX_STATS.
create or replace view view_index_stats as
select
a.index_name,
a.zeitstempel,
x.indexed_documents,
x.allocated_docids,
x.dollar_i_rows,
x.dollar_i_dsize,
x.index_frag,
x.garbage_docids,
x.garbage_size
from
ausgabe a,
xmltable(
'/CTXREPORT/INDEX_STATS'
passing a.resultat
columns
indexed_documents number path '/INDEX_STATS/STAT_INDEX_STATS/STAT_STATISTIC[@NAME="indexed documents"]',
allocated_docids number path '/INDEX_STATS/STAT_INDEX_STATS/STAT_STATISTIC[@NAME="allocated docids"]',
dollar_i_rows number path '/INDEX_STATS/STAT_INDEX_STATS/STAT_STATISTIC[@NAME="$I rows"]',
dollar_i_dsize number path '/INDEX_STATS/STAT_FRAG_STATS/STAT_STATISTIC[@NAME="total size of $I data"]',
index_frag varchar2(10) path '/INDEX_STATS/STAT_FRAG_STATS/STAT_STATISTIC[@NAME="estimated row fragmentation"]',
garbage_docids number path '/INDEX_STATS/STAT_FRAG_STATS/STAT_STATISTIC[@NAME="garbage docids"]',
garbage_size number path '/INDEX_STATS/STAT_FRAG_STATS/STAT_STATISTIC[@NAME="estimated garbage size"]'
) x
/
Diese View lässt sich nun wie eine Tabelle verwenden ...
SQL> select * from view_index_stats
INDEX_NAME ZEITSTEMPEL INDEXED_DOCUMENTS ALLOCATED_DOCIDS
---------- -------------------- ----------------- ----------------
DOLLAR_I_ROWS DOLLAR_I_DSIZE INDEX_FRAG GARBAGE_DOCIDS GARBAGE_SIZE
------------- -------------- ---------- -------------- ------------
IDX_TEXT 18.04.2013 14:43:49 10 10
56 198 0 % 0 0
1 Zeile wurde ausgewählt.
Nicht so schön ist die Spalte INDEX_FRAG - denn das XML, welches von INDEX_STATS generiert
wurde, enthält hier tatsächlich das Prozentzeichen - weshalb es nicht als NUMBER aufgefasst
werden kann - hierfür müssen wir in der View-Definition noch ein wenig was tun ...
create or replace view view_index_stats as select a.index_name, a.zeitstempel, x.indexed_documents, x.allocated_docids, x.dollar_i_rows, x.dollar_i_dsize, to_number(replace(x.index_frag, ' %', '')) as index_frag, x.garbage_docids, :
Danach ist auch die Spalte INDEX_FRAG vom Typ NUMBER und man kann nun numerische
Vergleiche durchführen. Analog dazu lassen sich auch die Token-Statistiken
entsprechend aufbereiten ... Dazu bauen wir eine zweite View ...
create or replace view index_stats_frag_tokens as
select
a.index_name,
a.zeitstempel,
x.token_text,
x.token_type,
to_number(replace(x.token_frag, ' %', '')) as token_frag
from
ausgabe a,
xmltable(
'/CTXREPORT/INDEX_STATS/STAT_FRAG_STATS/STAT_TOKEN_LIST/STAT_TOKEN'
passing a.resultat
columns
token_text varchar2(64) path '/STAT_TOKEN/STAT_TOKEN_TEXT',
token_type varchar2(50) path '/STAT_TOKEN/STAT_TOKEN_TYPE',
token_frag varchar2(20) path '/STAT_TOKEN/STAT_TOKEN_STATISTIC'
) x
/
select * from index_stats_frag_tokens
/
... deren Inhalt nun wie folgt aussieht ...
SQL> select * from index_stats_frag_tokens INDEX_NAME ZEITSTEMPEL TOKEN_TEXT TOKEN_TYPE TOKEN_FRAG ---------- -------------------- -------------------- -------------------- ---------- IDX_TEXT 18.04.2013 14:55:28 ZU 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WOLLEN 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WIRTSCHAFT 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WIRD 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WICHTIGER 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WERDEN 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WER 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WEITER 0:TEXT 0 IDX_TEXT 18.04.2013 14:55:28 WAHLKAMPF 0:TEXT 0 :
Lässt man das XML nun, wie schon erwähnt, per DBMS_SCHEDULER regelmäßig aktualisieren, so
hat man (wie im Data Dictionary) bequem nutzbare Views mit Statistiken zum Index. Diese
können nun natürlich auch für eine automatisierte Verarbeitung genutzt werden. So könnte
ein Job regelmäßig alle Tokens optimieren (CTX_DDL.OPTIMIZE mit OPTLEVEL_TOKEN),
die eine bestimmte Fragmentierung überschreiten. Gleiches gilt natürlich auf Indexebene.
Auch
die Integration mit Management-Werkzeugen wie dem Oracle Enterprise Manager ist kein Problem. In
der deutschsprachigen DBA Community
ist beschrieben, wie man eine eigene "Metrik", basierend auf einer SQL-Abfrage einrichtet. Nimmt man hierfür die erstellten Views, so kann der Enterprise Manager einen Alert senden, sobald
die Indexfragmentierung einen bestimmten Schwellenwert übersteigt. Die professionelle Wartung einer
Oracle TEXT-Installation ist damit kein Problem mehr ...
Dienstag, 5. März 2013
Alle Posts auf einen Blick
Um einen besseren Überblick über die schon veröffentlichten Posts in diesem Blog zu bekommen, an dieser Stelle eine aktuelle Linksammlung ...
Grundsätzliche Themen: Administration, Index anlegen ...
Grundsätzliche Themen: Administration, Index anlegen ...
- Performance beim CREATE INDEX
- FILE_DATASTORE und Security oder: Was ist die FILE_ACCESS_ROLE?
- 11.2.0.4 und Oracle Text Patch
- Ein Einstieg in Oracle Text
- Oracle Text Komponente überprüfen und installieren
- Welche DR$-Tabellen gibt es und wozu sind sie gut?
- Der CTXCAT-Index
- DML Operationen und der Oracle Text Index
- Index Synchronisierung und Transactional Parameter
- Index-Optimierung: Einige Grundlagen
- Tablespace und mehr: Storage-Klausel für den Oracle-TEXT Index
- Stopwörter und Stoplisten: Unwichtige Wörter ...
- Einstellungen für einen Textindex: Komposita, Printjoins, Skipjoins, Mixed Case und mehr ...
- Einzelne Zeilen vom Index ausnehmen - Parameter "FORMAT COLUMN"
- Einige Gedanken zu Oracle TEXT und Tabellen-Partitionierung
- Der Textindex und der Datentyp SECUREFILE
- Oracle TEXT und Database Links ...
- Hochverfügbarer Textindex mit Schattenindex-Technologie
- Arbeiten mit einem Thesaurus in Oracle TEXT
- Mehrere Sprachen in einer Tabelle unterstützen: MULTI_LEXER
- Oracle Text Features im Überblick - 11g Release 1, 11g Release 2
- DBMS_PCLXUTIL zur Erzeugung von lokalen Indizes
- Oracle 12c Alle 12c Text Features auf einen Blick!
- Oracle 12c: Automatic Near Real-Time Index
- Transaktionen und CTX_DDL: COMMIT oder nicht COMMIT?
- 12c Feature: $I Tabelle mit neuer Storage Preference BIG_IO
- Statistiken im Oracle Text Umfeld
- Mehr Performance durch Index-Preloading
- Fragmentierung feststellen mit INDEX_STATS
- Monitoren von Oracle Text Indizes: Grundsätzliches
- Query Result Set Feature
- CTX_QUERY.EXPLAIN: Erklärungen für eine TEXT-Abfrage
- Suchverhalten der Anwender monitoren: Abfrage-Analyse mit CTX_REPORT
- Indexstatistiken (INDEX_STATS) im XML-Format: Oracle TEXT Management einfach automatisieren!
- Suche in JSON Dokumenten in 12.2: wie geht das?
- Ergebniscache für TEXT-Abfragen: Oracle12c TEXT Query Filter Cache
- Oracle12c: Verändertes Verhalten bei Datastore Triggern
- Oracle12c: Neues Feature 'Pattern Stopclass'
- Oracle12c: Unterstützung für XML-Namespaces in Oracle TEXT
- Keyword in Context: CTX_DOC.SNIPPET
- Ähnliche "Tokens" mit der BROWSE_WORDS-Funktion finden
- Abfragen vordefinieren: Stored Query Expressions (SQE)
- Ergebnisse zählen: Nicht mit count(*), sondern mit COUNT_HITS!
- Viele Abfragen auf einmal: Query Relaxation
- Wie ähnlich soll es sein ...? Ein paar Worte zum FUZZY-Operator
- Neues Oracle TEXT-Feature NAME SEARCH
- Unscharfe Namenssuche (Name Search) mit NDATA
- Name Matching (NDATA) mit einem Thesaurus "erweitern"
- Mächtige Suchabfragen: PL/SQL-Funktionen innerhalb CONTAINS()
- Suche nach "Aktenzeichen" oder "Autonummer" mit Oracle TEXT: Sind Printjoins die Lösung?
- Section"-Suche in Oracle TEXT
- Die Wordlist und das wildcard_maxterms Attribut
- "Sicheres" Suchen: Oracle TEXT und die "Virtual Private Database"
- Scoring mit Oracle Text
- Filter Preferences - Grundsätzliches
- USER_DATASTORE ... indiziert wirklich alles
- Nochmal USER_DATASTORE: Ein umfassendes Beispiel - Teil I
- Mehrere Tabellenspalten indizieren: MULTICOLUMN_DATASTORE
- MDATA Section und MULTI_COLUMN_DATASTORE
- Anwendungsbeispiel für MULTI_COLUMN_DATASTORE, MDATA und Operatoren ACCUM und WEIGHT
- Metadaten-Suche mit MDATA Section
- Mixed Queries in 11g
- Abfrage-Optimierung mit Composite Domain Index
- Treffer zählen:COUNT_HITS und Mixed Queries zusammen!
Abonnieren
Posts (Atom)
Beliebte Postings
-
Wie kann man überprüfen, dass die Oracle Text Umgebung korrekt installiert ist? Wie kann man Oracle Text nachinstallieren? Das sind häufig ...
-
Oracle TEXT ist eine in die Datenbank integrierte Volltextrecherche, die in allen Datenbankeditionen enthalten ist (kostet also nichts extra...
-
Beim Erstellen eines Oracle TEXT-Index kann man eine ganze Menge Einstellungen vornehmen. Im letzten Posting ging es um das Thema St...
-
Wie in vorangegangen Blogs gezeigt wurde, kann die sogenannte Mixed Query Problematik - eine Kombination aus relationalem und Volltextrech...
-
MDATA Sections sind in 10 g eingeführt worden, um gemischte Abfragen (auch mixed queries genannt) - also Abfragen mit Text- und relational...