==== Mit einem Thesaurus und Oracle Text arbeiten ===
Einführung in Oracle Text => [[dba:oracle_text|Oracle Text - Volltext Suche über Text Dokumente]]
Über einen Thesaurus werden Relationen zwischen Wörtern abgebildet.
{{ :prog:apex:apex_katze_v03.png?direct&200|Oracle Text Katze V2}}
Der Thesaurus im Informationswissenschaftlichen Sinn (als Dokumentationssprache) wird in der DIN 1463 wie folgt definiert: Ein Thesaurus im Bereich der Information und Dokumentation ist eine geordnete Zusammenstellung von Begriffen und ihren (vorwiegend natürlichsprachigen) Bezeichnungen, die in einem Dokumentationsgebiet zum Indexieren, Speichern und Wiederauffinden dient.
Er ist durch folgende Merkmale gekennzeichnet:
* Begriffe und Bezeichnungen werden eindeutig aufeinander bezogen ("terminologische Kontrolle"), indem Synonyme möglichst vollständig erfasst werden:
* Homonyme und Polyseme besonders gekennzeichnet werden
* für jeden Begriff eine Bezeichnung (Vorzugsbenennung, Begriffsnummer oder Notation) festgelegt wird, die den Begriff eindeutig vertritt.
* Beziehungen zwischen Begriffen (repräsentiert durch ihre Bezeichnungen) werden dargestellt.
Ein Thesaurus ist dann wiederum die Voraussetzung das ein Dokument über einen [[dba:oracle_text_index_themes|Oracle Theme Index]] indiziert und gesucht werden kann.
Da die Definition diese Regel doch sehr anspruchsvoll werden kann, ist ein sehr sinnvoller Einsatz in der Klassifizierung von Dokumenten zu finden, z.b. über den [[prod:oracle_text_ctxrule_index|CTXRULE Index]].
Allerdings stehen diese Thesaurus nur für wenige Sprache wie Englisch zur Verfügung, meist muss ein eigener Thesaurus erstellt werden.
Auch passen allgemeine Thesaurus oft gar nicht so zur eigentlichen Aufgabe, wie das Finden von alternativen Beziehungen in Fachdokumenten.
----
==== Die verschiedenen Relationen zwischen Wörtern ====
Eine Typische Relation zwischen zwei Wörtern ist das strikte [[https://de.wikipedia.org/wiki/Synonym|Synonym]] (SN) wie "Apfelsine" "Orange", das heißt beide Begriffe stehen in der Hauptsache tatsächlich für das gleiche.
Die Begriffe können aber im Textkontext durchaus eine andere Bedeutung entfalten.
In der Sprache gibt es im Regelfall selten zwei Wörter für exakt die gleiche Bedeutung.
Allerdings gibt es viele Verwandtschaftsgrade zwischen verschiedenen Wörtern, die eine ähnliche Bedeutung im Text Kontext entfalten können und/oder eine zusätzliche Wertung enthalten.
Alles diese Beziehung können in eine Thesaurus modelliert werden und dann über Oracle Text auch auf den Text zur Suche verwendet werden.
=== Thesaurus Operatoren ===
Die Operatoren beschreiben die Relation zwischen den Wörtern und können so dann später bei der Suche eingesetzt werden,
^Operator ^Abkürzungen nach ISO 2788^Syntax^
|Synonym |SYN|SYN(term[,thes]) |
|Preferred Term |PF|PT(term[,thes]) |
|Related Term |RT|RT(term[,thes]) |
|Narrower Term |NT|NT(term[,level[,thes]]) |
|Broader Term |BT|BT(term[,level[,thes]]) |
=== Synonym SN - gleichsinnige Ausdrücke===
**SYN(PKW)** findet Dokumente, die sowohl PKW als auch Auto oder Personenkraftwagen enthalten.
**Auto** => Synonym für PKW => **PKW** Synonym für => **Personenkraftwagen**
=== Preferred Term PT - bevorzugter Ausdruck ===
**PT(Handy)** findet Dokumente, die sowohl Handy als auch Mobiltelefon oder Funktelefon enthalten.
**Handy** = Preferred Term für Mobiltelefon => **Mobiltelefon** = Preferred Term für **Funktelefon**
=== Related Term RT - verwandter Ausdruck===
**RT(Apfel)** findet Dokumente, die sowohl Apfel als auch Birne oder Quitte enthalten.
Assoziationsrelation RT (für RELATED TERM), die auf irgendeine Art verwandte Begriffe miteinander verbindet, zwischen denen keine der beiden anderen Relationen besteht.
Hierunter fällt eine Vielzahl von Verwandtschaftsverhältnissen.
* Determinationsbegriff - Determinans: Tierernährung RT Tier
* Logische Gleichordnung: Apfel RT Birne
* Nebenordnung:
* Bayern RT Hessen
* Dotter RT Eiklar
* Eiklar RT Eischale
* Antonymie: Hitze RT Kälte
* Folge-/Nachfolgebeziehungen: Vater RT Sohn
* Affinität: Buch RT Lesen
=== Narrower Term NT - engerer Ausdruck===
**NT(AUTO)** findet Dokumente, die sowohl Auto als auch Automotor oder Antrieb enthalten
**Auto** => Narrower Term für Automotor => **Automotor** Narrower Term für Maschine => **Antrieb**
=== Broader Term BT - weitere Ausdrücke===
**BT(PKW)** findet Dokumente, die sowohl Fortbewegungsmittel als auch Fahrzeug oder PKW enthalten
**Fortbewegungsmittel** => broader term für Fahrzeug => **Fahrzeug** broader term für PKW => **PKW**
----
====Beispiel für einen eigenen Thesaurus ====
Ein eigener Thesaurus lässt sich mit PL/SQL oder in einer Text Datei erstellen
===PL/SQL Beispiel===
Mit dem [[https://docs.oracle.com/database/121/CCREF/cthes.htm|CTX_THES Package]] kann der Thesaurus auch über PL/SQL angelegt werden.
Beispiel:
-- löschen und neu anlegen
EXEC CTX_THES.DROP_THESAURUS(name => 't_fahrzeuge');
Begin
-- create the empty thesaurus case insensitiv
CTX_THES.Create_Thesaurus (name => 't_fahrzeuge', casesens=> false);
--create a Phrase to the thesaurus t_fahrzeuge
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'fahrzeug' );
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'automobil' );
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'auto' );
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'cabriolet' );
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'cabrio' );
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'lastkraftwagen' );
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'PKW' );
CTX_THES.create_phrase ( tname => 't_fahrzeuge', phrase => 'LKW' );
-- define a relation to this phrasees
CTX_THES.CREATE_RELATION(
tname => 't_fahrzeuge',
phrase => 'fahrzeug',
rel => 'NT',
relphrase => 'automobil' );
CTX_THES.CREATE_RELATION(
tname => 't_fahrzeuge',
phrase => 'fahrzeug',
rel => 'NT',
relphrase => 'lastkraftwagen' );
CTX_THES.CREATE_RELATION(
tname => 't_fahrzeuge',
phrase => 'automobile',
rel => 'NT',
relphrase => 'cabriolet' );
CTX_THES.CREATE_RELATION(
tname => 't_fahrzeuge',
phrase => 'auto',
rel => 'SYN',
relphrase => 'automobile' );
CTX_THES.CREATE_RELATION(
tname => 't_fahrzeuge',
phrase => 'cabrio',
rel => 'SYN',
relphrase => 'cabriolet' );
CTX_THES.CREATE_RELATION(
tname => 't_fahrzeuge',
phrase => 'PKW',
rel => 'SYN',
relphrase => 'automobile' );
CTX_THES.CREATE_RELATION(
tname => 't_fahrzeuge',
phrase => 'LKW',
rel => 'SYN',
relphrase => 'lastkraftwagen' );
end;
/
Testen:
-- test the thesaurus NT
select CTX_THES.NT('fahrzeug',1,'t_fahrzeuge') as NT from dual;
NT
----------------------------------------
{FAHRZEUG}|{AUTOMOBIL}|{LASTKRAFTWAGEN}
select CTX_THES.NT('automobil',1,'t_fahrzeuge') as NT from dual;
NT
-----------------------------------------
{AUTOMOBIL}|{CABRIOLET}
declare
xtab ctx_thes.exp_tab;
begin
ctx_thes.nt(xtab, 'fahrzeug', 2, 't_fahrzeuge');
for i in 1..xtab.count loop
dbms_output.put_line(lpad(' ', 2*xtab(i).xlevel) ||
xtab(i).xrel || ' ' || xtab(i).xphrase);
end loop;
end;
/
PHRASE FAHRZEUG
NT AUTOMOBIL
NT CABRIOLET
NT LASTKRAFTWAGEN
select CTX_THES.SYN('automobile','t_fahrzeuge') as SYN from dual;
SYN
-------------------------
{AUTOMOBILE}|{AUTO}|{PKW}
declare
xtab ctx_thes.exp_tab;
begin
ctx_thes.syn(xtab, 'automobile', 't_fahrzeuge');
for i in 1..xtab.count loop
dbms_output.put_line(lpad(' ', 2*xtab(i).xlevel) ||
xtab(i).xrel || ' ' || xtab(i).xphrase);
end loop;
end;
/
PHRASE AUTOMOBILE
SYN AUTO
SYN PKW
-- alle NT
declare
v_exp ctx_thes.exp_tab;
v_expi ctx_thes.exp_tab;
begin
ctx_thes.thes_tt(v_exp,'t_fahrzeuge');
for i in 1..v_exp.count loop
dbms_output.put_line(lpad(' ',2*v_exp(i).xlevel)||
v_exp(i).xrel||' '||v_exp(i).xphrase);
ctx_thes.nt(v_expi, v_exp(i).xphrase, 1, 't_fahrzeuge');
for i in 1..v_expi.count loop
dbms_output.put_line(lpad(' ',2*v_expi(i).xlevel)||
v_expi(i).xrel||' '||v_expi(i).xphrase);
end loop;
end loop;
end;
Den Thesaurus als Regelwerk auslesen:
variable t_export clob
set long 1000000
declare
v_export clob;
begin
ctx_thes.export_thesaurus(name => 't_fahrzeuge',thesdump => v_export);
:t_export:=v_export;
end;
/
print t_export
undefine t_export
Erzeugt die folgende Datei:
T_EXPORT
--------------
AUTO
UF PKW
UF AUTOMOBILE
AUTOMOBIL
BT FAHRZEUG
NT CABRIOLET
AUTOMOBILE
UF AUTO
UF PKW
CABRIO
UF CABRIOLET
CABRIOLET
UF CABRIO
BT AUTOMOBIL
FAHRZEUG
NT AUTOMOBIL
NT LASTKRAFTWAGEN
LASTKRAFTWAGEN
UF LKW
BT FAHRZEUG
LKW
UF LASTKRAFTWAGEN
PKW
UF AUTO
UF AUTOMOBILE
=== Werte über eine Text Datei einlesen ===
Soll solch eine eigener Thesaurus später als Basis für einen Theme Index stehen, muss der User CTXSYS verwendet und der Thesaurus case sensitve angelegt werden!
Aufgabe: Eine Suche nach "Delphi" soll auch alle Dokumente mit dem Begriff "Pascal" und "Borland" finden.
Dazu wird eine Text Datei mit den Relationen erstellt:
Pascal
SYN Delphi
RT Borland
SQL
RT PL/SQL
Java
NT SCALA
NT Groovy
JavaScript
NT CoffeeScript
Python
NT Juliactx
Vor dem Laden in die Datenbank auf die Sprache Einstellungen achten!
Die Sprache der Laufzeitumgebung und die Sprache der Datenbank legen später fest unter welcher Sprache der Thesaurus angewandt wird!
Im meiner Umgebung (Powershell):
echo $ENV:NLS_LANG
AMERICAN_AMERICA.UTF8
-- in der DB:
select sys_context ('USERENV', 'LANGUAGE') as NLS_LANG_Parameter from dual;
AMERICAN_AMERICA.AL32UTF8
Löschen falls schon exisiert:
sqlplus ctxsys/ctxsys
EXEC CTX_THES.DROP_THESAURUS(name => 't_prog_lang');
In die Datenbank laden mit **ctxload **, case sensitive da später als Basis für Oracle Theme Index gedacht!:
ctxload -user ctxsys/xxxxxx -thes -name t_prog_lang -file prog_lang.txt -thescase y
Connecting...
Creating thesaurus t_prog_lang...
Thesaurus t_prog_lang created...
Processing...
12 lines processed successfully
Beginning insert...12 lines inserted successfully
Disconnected
In der Datenbank nach dem obigen Muster testen:
select CTX_THES.NT('java',1,'t_prog_lang') as NT from dual;
NT
---------------------
{JAVA}|{SCALA}|{GROOVY}
Um diesen Thesaurus wiederum im Oracle Text Theme Index zu verwenden muss der Thesaurus übersetze werden.
Übersetzen mit **ctxkbtc**:
ctxkbtc -user ctxsys/xxxxxx -name t_prog_lang
Oracle Text knowledge base extension: thesaurus compiler
Connecting...
No old extended knowledge base to delete.
Processing thesaurus: T_PROG_LANG
Processed 11 terms.
Done processing thesaurus: T_PROG_LANG
Compiling and writing new flat files.
Writing extended knowledge base to files.
.............................................
Oracle Text knowledge base successfully extended.
Disconnected
Der Compiler erzeugt dann unter $ORACLE_HOME\D:\oracle\products\12.1.0.2\dbhome_1\ctx\data neue Einträge, in meine Fall unter enlx in den dref*US.dat Dateien.
**Problem mit ctxkbtc und anderen User als ctxsys**
Fehlermeldung:
Processing thesaurus: T_PROG_LANG
ORA-00942: table or view does not exist
Lösung: Nur mit dem CTXSYS User möglich!
----
==== Mit einem Thesaurus suchen====
Für die Suche verwenden wir den obigen über eine Text Datei angelegten Thesaurus t_prog_lang.
In den Texten kann dann mit einem **contains(text,'SYN(Pascal, t_prog_lang)')** gesucht werden.
Zur Suche mit Oracle Text siehe auch [[prog:oracle_text_contains#iso_2788_konformer_thesaurus_-_syn_nt_bt|Oracle Text - In Texten suchen]]
===Beispiel Daten anlegen===
Beispiel Tabelle:
CREATE TABLE prog_docs ( id NUMBER(11) PRIMARY KEY, text varchar2(4000));
INSERT INTO prog_docs VALUES (1,'Borland ist einer der Pioniere der Programmiersprachen');
INSERT INTO prog_docs VALUES (2,'Delphi baut auf einem Standard auf');
INSERT INTO prog_docs VALUES (3,'CoffeeScript erleichtert die Web Entwicklung');
INSERT INTO prog_docs VALUES (4,'SQL erleichert die Datenbank Entwicklung');
commit;
EXEC ctx_ddl.create_preference( 'gpi_lexer', 'BASIC_LEXER' );
EXEC ctx_ddl.set_attribute ('gpi_lexer', 'INDEX_THEMES', 'YES');
-- drop INDEX idx_prog_docs;
CREATE INDEX idx_prog_docs ON prog_docs(text)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('LEXER gpi_lexer')
/
===Suchen===
Die Suchfunction auf dem Thesaurus wird dem Contains Operator übergeben:
SELECT * FROM prog_docs WHERE contains(text, 'NT(Pascal,1,t_prog_lang)') >0;
-- findet Borland, da wir zuvor Borland als NT von Pascal definiert haben
1 Borland ist einer der Pioniere der Programmiersprachen
SELECT * FROM prog_docs WHERE contains(text, 'SYN(Pascal,t_prog_lang)') >0;
-- findet Delphi, da wir zuvor Pascal und Delphi als Synonyme definiert haben
2 Delphi baut auf einem Standard auf
Bzgl der Syntax kann man sich an den NT/BT/SYN Funktionen des [[ http://docs.oracle.com/database/121/CCREF/cthes.htm#CCREF2173|CTX_THES Packages]] orientieren.
----
====Quellen ====
Oracle:
* http://docs.oracle.com/database/121/CCREF/cexec.htm#CCREF2198
* https://docs.oracle.com/database/121/CCREF/cthes.htm#CCREF1600
Web - Allgemeines über Thesauren:
* http://www.cis.uni-muenchen.de/kurse/pmaier/TC_07/
* http://www.cis.uni-muenchen.de/kurse/pmaier/TC_07/material/Thesaurus.ppt