==== 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