Benutzer-Werkzeuge

Webseiten-Werkzeuge


prog:oracle_text_highlight

Oracle Text - Die Treffer einer Oracle Volltext Abfrage in der Ergebnismenge optisch hervorheben

Ab 10g/11g/12c

Einführung in Oracle Text ⇒ Oracle Text - Volltext Suche über Text Dokumente

Nach dem ein Dokument mit einer Volltext Suche gefunden wurde, stellt sich natürlich die Frage, wo denn im Text etwas erkannt wurde.

Für die Aufbereitung der Trefferliste/Dokumentanzeige wird dazu das CTX_DOC Package eingesetzt.

Für einzelne Textabschnitt kann mit „CTX_DOC.HIGHLIGHT“ die Offset Position dazu bestimmt werden, oder mit CTX_DOC.SNIPPET ein Teil ausgeschnitten werden.

Ab 12c kann mit Forward Indexing das ganze auch noch beschleunigt werden, allerdings wird dann auch mehr Speicherplatz in der Datenbank benötigt.

Teilbereiche aus dem Dokument mit dem gefundenen Wort hervorheben

So kann zum Beispiel mit „CTX_DOC.SNIPPET“ der Treffer Text Abschnitt angezeigt werden:

--Session so setzen wie die Spalte in der Tabelle gefunden werden soll
--Fehlt das, siehe folgender Fehler
 
EXEC ctx_doc.set_key_type('ROWID');
 
-- Abfragen und Ergebniss mit ermitteln
 
SELECT CTX_DOC.SNIPPET(
	 index_name => 'IDX_DOC_FILES'
	,textkey    => rowid
	,text_query => '?Hunt'
	,starttag   => '<span style="color:#034F84; background-color:#F7CAC9">' 
	,endtag     => '</span>'
	,separator  => '<b>...</b>') AS textfragment 
FROM texte WHERE  contains(text, '?Hunt') >0
/

Leider klappt das dann nicht, weil im ersten Test das setzen von „ctx_doc.set_key_type('ROWID') “ vergessen wurde! Der Fehler:

ERROR at line 1:
ORA-29903: error in executing ODCIIndexFetch() routine
ORA-20000: Oracle Text error:
DRG-50857: oracle error in drvdoc.get_rowid
ORA-01410: invalid ROWID
ORA-06512: at "CTXSYS.DRUE", line 160
ORA-06512: at "CTXSYS.CTX_DOC", line 2606
ORA-06512: at line 1

Wird nur mit ID auf die PK Spalte verwiesen erhalten wir den folgenden Fehler:

ERROR at line 1:
ORA-20000: Oracle Text error:
DRG-10826: no document WITH the specified textkey IS found
ORA-06512: at "CTXSYS.DRUE", line 160
ORA-06512: at "CTXSYS.CTX_DOC", line 2606
ORA-06512: at line 1

Hier lag der Fehler im falschen CTX Index Namen, gab mehrere davon .-(.

Wie muss das nun ohne Fehler aufgerufen werden?

Der Parameter „textkey“ kann entweder auf der RowID oder auf den Primary Key der Tabelle arbeiten.

Ist der PK aus mehreren Werten zusammengesetzt, muss mit CTX_DOC.PKENCODE der entsprechende Schlüssel aufgebaut werden.

Warum aber funktioniert das in den obigen Beispiel erst mal einfach nicht?

Lösungsmöglichkeiten:

  • Überprüfen, ob auch der richtige Index referenziert wird, bei einem falschen Index wird dieser durchsucht aber der Key kann ja nicht passen (na hoffentlich!)
  • Überprüfen, ob die richtige Methode für den Key Zugriff zuvor ausgewählt wurde
    • exec ctx_doc.set_key_type('PRIMARY_KEY') (Default!) bei textkey ⇒ <PK_SPALTE>
    • exec ctx_doc.set_key_type('ROWID') bei textkey ⇒ rowid

Das ganze Dokument als Text mit Markierung anzeigen

Hilfsfunktion zum Anzeigen eines ganzen Dokumentes:

CREATE OR REPLACE FUNCTION ctx_apex_markup ( p_pk  varchar2
                                           , p_queryString varchar2
					   , p_index_name  varchar2
					) 
RETURN CLOB 
IS 
    -- temporären Lob für das Ergebnis
    v_storage CLOB; 
BEGIN 
     -- Wie soll der Parameter Text Key ausgewertet werden!
     ctx_doc.set_key_type('PRIMARY_KEY');        
 
     -- Markup Funktion in Memory nützen
     ctx_doc.markup (index_name  => UPPER(p_index_name)
                     ,textkey    => p_pk
                     ,text_query => p_queryString
                     ,restab     => v_storage 
                     ,starttag   => '<span style="color:#034F84; background-color:#F7CAC9">' 
                     ,endtag     => '</span>');                            
 
   RETURN v_storage; 
 
END ctx_apex_markup;
/ 

Das Clob Dokument muss natürlich von der rufenden Umgebung auch verarbeitete werden können, ab 32K muss hier also noch etwas mehr getan werden.

Möchte man die Starttag/endtag Parameter nicht angeben, kann auch mit dem Parameter „tagset ⇒ 'HTML_NAVIGATE'“ gearbeitet werden.

Bei kurzen Texten klappt das aber so ganz gut:

SELECT ctx_apex_markup(
	  p_index_name    => 'IDX_TEXTE'
	, p_pk            => to_char(ID)
	, p_queryString   => '?Hunt'
	)
	AS text
FROM texte WHERE  contains(text, '?Hunt') >0
/

Oracle 12c New Feature - Forward Indexing

Um das Higlighting, Snippet und das Markup zu beschleunigen wird beim Anlegen des Oracle Text Domain Indexes eine neue zusätzliche Tabelle eingeführt, die $O, ein Mapping auf die $I.

Parameter setzen:

EXEC ctx_ddl.create_preference('GPI_STORAGE ', 'BASIC_STORAGE' )
 
EXEC ctx_ddl.set_attribute    ('GPI_STORAGE ', 'FORWARD_INDEX', 'TRUE' )
EXEC ctx_ddl.set_attribute    ('GPI_STORAGE ', 'SAVE_COPY', 'PLAINTEXT' )

siehe auch Oracle Text für die Indizierung binärer Daten verwenden

Leider gleich mal auf eine Bug gelaufen

Cursor von CTX_DOC.SNIPPET werden nicht geschlossen - ORA-01000: maximum open cursors exceeded

Bug 20892798 : MANY CURSORS OPENED WHEN USING FORWARD INDEXING LEADING TO ORA-01000 ERROR

Kein FIX öffentlich – Falls gleicher Fehler Auftritt erneuten Bug mit Prio eröffnen und Druck machen!


Quellen

Cookies helfen bei der Bereitstellung von Inhalten. Durch die Nutzung dieser Seiten erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Rechner gespeichert werden. Weitere Information
"Autor: Gunther Pipperr"
prog/oracle_text_highlight.txt · Zuletzt geändert: 2016/05/11 19:41 von Gunther Pippèrr