1. Start
  2. Unternehmen
  3. Blog
  4. Wie funktioniert Oracle Hybrid Vector Search?

Wie funktioniert Oracle Hybrid Vector Search?

Bei der Suche innerhalb einer 26ai Datenbank steht man vor der Entscheidung, ob man eine Textsuche oder eine Vektorsuche verwendet. Die Lösung kann dabei einfach sein: Man verwendet beides, die hybride Suche!
Oracle stellt mit DBMS_HYBRID_SEARCH ein Package zur Verfügung, mit dem sich Textsuche und Vektorsuche kombinieren lassen. Dieser Blogbeitrag zeigt die Anwendung der hybride Suche an einem einfachen Beispiel.

 

Ausgangssituation:

In diesem Beispiel werden Daten der englischsprachigen Wikipedia verwendet. Die folgende Tabelle enthält alle Artikel, die auf den Artikel Dresden verweisen.

Die Tabelle beinhaltet Id, Name und den ersten Absatz des Artikels. Die Tabellenstruktur sieht folgendermaßen aus:

 

DESC wikipedia

Name          Null?       Type                    
_____________ ___________ _______________________ 
PAGE_ID       NOT NULL    NUMBER(10)              
PAGE_TITLE                VARCHAR2(200)           
PARAGRAPH                 VARCHAR2(32000 CHAR)  

 

Um entsprechend große Texte in einer Spalte vom Typ VARCHAR2 zu speichern, war es im Vorfeld notwendig, durch die Verwendung des "Extended Data Types" auf PDB-Ebene Datentyplängen bis 32767 Bytes zuzulassen.
Im folgenden wird ein Datensatz der Tabelle Wikipedia angezeigt.

 

SELECT *
FROM wikipedia
WHERE page_title LIKE 'Theaterplatz%';

PAGE_ID     PAGE_TITLE                PARAGRAPH                                                                                                                                   
___________ _________________________ ___________________________________________________________________________________________________________________________________________ 
67143572    Theaterplatz (Dresden)    The Theaterplatz (English: Theatre Square) in Dresden is a historic square in the city. It is located in the west of the inner old town.

 

Außerdem wird ein Einbettungsmodell für die Vektorsuche benötigt. Hierfür wurde das frei verfügbare Modell 
all-MiniLM-L6-v2 bereits unter dem Namen wp_model in die Datenbank geladen.

 

Einführung in die hybride Suche:

Für eine Vektorsuche auf der Spalte paragraph müssten die dort gespeicherten Absätze mit dem vorhandenen Einbettungsmodell in Vektoren überführt werden. Diese Vektoren werden standardmäßig in einer zusätzlichen Spalte gespeichert, auf der dann zur Beschleunigung der Vektorsuche ein Vektor-Index erstellt werden kann. Durch die Vektorsuche kann dann mittels Distanzfunktion die Ähnlichkeit einer Suchanfrage zu den vorhandenen Absätzen bestimmt werden.
Für die Erstellung eines hybriden Index ist es hingegen nicht notwendig die eingebetteten Vektoren in einer separaten Spalte zu speichern. Der hybride Index kann unter Angabe des Einbettungsmodells direkt auf der Spalte paragraph erstellt werden.

 

CREATE HYBRID VECTOR INDEX wp_hybrid_index
ON wikipedia(paragraph)
PARAMETERS('Model wp_model');

 

Ein hybrider Index kann sogar erstellt werden, wenn auf derselben Spalte bereits ein herkömmlicher Index definiert ist.
Auf Basis des hybriden Index können nun hybride Suchanfragen formuliert werden. Dabei müssen die Suchbegriffe für die Textsuche, der Suchtext der Vektorsuche, sowie weitere Parameter im JSON-Format übergeben werden.

 

SELECT JSON_SERIALIZE(
   DBMS_HYBRID_VECTOR.SEARCH(
       JSON(
           '{  "hybrid_index_name"  : "wp_hybrid_idx",
               "text":
                   {"contains"      : "Theaterplatz"},
               "vector":
                   {"search_text"   : "Theaterplatz in Dresden",
                    "search_mode"   : "DOCUMENT",
                    "aggregator"    : "AVG"},
               "return":
                   {"values"        : [ "rowid", "text_score", "vector_score", "score" ],
                    "topN"          : 1}
           }'
       )
   ) RETURNING CLOB PRETTY
) AS suchergebnis;

SUCHERGEBNIS                                                                        
___________________________________________________________________________________ 
[
 {
   "rowid" : "AAAZ4tAAAAAAqOnAAK",
   "text_score" : 13,
   "vector_score" : 86.05,
   "score" : 79.41
 }
]

 

Im Beispiel wurde eine hybride Suche durchgeführt. Zum einen wurde nach dem Text "Theaterplatz" mittels Textsuche gesucht, zum anderen wurde eine Vektorsuche für "Theaterplatz in Dresden" durchgeführt. Als Ergebnis erhält man die rowid des entsprechenden Datensatzes, sowie verschiedene scores. Das Suchergebnis wird im JSON-Format angezeigt.

Für die Textsuche erhält man einen text_score, ein Bewertungsmaß von 0 bis 100, welches misst, wie oft der Suchtext im Text des jeweiligen Datensatzes vorkommt. Je höher der entsprechende text_score, umso häufiger kommt der Suchbegriff, bzw. die Suchbegriffe im durchsuchten Text vor. 
Weiterhin erhält man einen vector_score für die Vektorsuche. Der vector_score liegt ebenfalls zwischen 0 und 100 und gibt die Ähnlichkeit der Suchtext zum entsprechenden Text des Datensatzes an. Je höher der vector_score ist, desto ähnlicher sind Suchtext und Text des jeweiligen Datensatzes. 
Der score entspricht der Gesamtbewertung und wird standardmäßig als gewichteter Durchschnitt aus text_score und vector_score (im Verhältnis 1:10) berechnet.

Da man nur die rowid des Datensatzes erhält, kann man nicht direkt sehen, welcher Wikipedia-Artikel als Ergebnis zurückgegeben wurde. Dafür muss man die Ergebnisdaten in Tabellenform bringen und mit der Tabelle wikipedia verknüpfen.

 

SELECT scores.text_score, scores.vector_score, scores.score, wp.page_title
FROM JSON_TABLE(
       (SELECT JSON(
           DBMS_HYBRID_VECTOR.SEARCH(
               JSON(
                   '{  "hybrid_index_name"  : "wp_hybrid_idx",
                       "text":
                           {"contains"      : "Theaterplatz"},
                       "vector":
                           {"search_text"   : "Theaterplatz in Dresden",
                            "search_mode"   : "DOCUMENT",
                            "aggregator"    : "AVG"},
                       "return":
                           {"values"        : [ "rowid", "text_score", "vector_score", "score" ],
                            "topN"          : 1}
                   }'
               )
           )
       )),
       '$[*]' 
       COLUMNS (row_id CHAR(18) PATH '$."rowid"',
                score NUMBER(5,2) PATH '$.score',
                 text_score NUMBER(5,2) PATH '$.text_score',
                 vector_score NUMBER(5,2) PATH '$.vector_score')
    ) scores
    JOIN wikipedia wp ON (scores.row_id = wp.rowid)
ORDER BY scores.score DESC;

TEXT_SCORE    VECTOR_SCORE    SCORE    PAGE_TITLE            
_____________ _______________ ________ _________________________ 
13            86.05           79.41    Theaterplatz (Dresden)    

 


Vergleich Text-, Vektor- und Hybridsuche:

Das Package DBMS_HYBRID_VECTOR bietet dabei nicht nur die Möglichkeit der hybriden Suche. Bei Bedarf kann auch eine reine Textsuche oder eine reine Vektorsuche ausgeführt werden. Bei der reinen Textsuche werden nur die Suchbegriffe angegeben, wohingegen bei der reinen Vektorsuche nur der Suchtext verwendet wird.

Wir betrachten diese drei Möglichkeiten nun anhand der Suche nach barocken Gebäuden in Dresden. Im ersten Beispiel führen wir eine reine Textsuche durch.

 

SELECT scores.text_score, scores.vector_score, scores.score, wp.page_title
FROM JSON_TABLE(
       (SELECT JSON(
           DBMS_HYBRID_VECTOR.SEARCH(
               JSON(
                   '{  "hybrid_index_name"  : "wp_hybrid_idx",
                       "text":
                           {"contains"      : "baroque, building, dresden"},
                       "return":
                           {"values"        : [ "rowid", "text_score", "vector_score", "score" ],
                            "topN"          : 6}
                   }'
               )
           )
       )),
       '$[*]' 
       COLUMNS (row_id CHAR(18) PATH '$."rowid"',
                score NUMBER(5,2) PATH '$.score',
                 text_score NUMBER(5,2) PATH '$.text_score',
                 vector_score NUMBER(5,2) PATH '$.vector_score')
    ) scores
    JOIN wikipedia wp ON (scores.row_id = wp.rowid)
ORDER BY scores.score DESC;

TEXT_SCORE    VECTOR_SCORE    SCORE    PAGE_TITLE                     
_____________ _______________ ________ ______________________________ 
72            0       	      72       Frauenkirche, Dresden          
72            0               72       Vineyard Church (Dresden)      
71            0               71       Romanus House                  
71            0               71       Dresden Museum of Ethnology    
70            0               70       Pillnitz                       
70            0               70       Großer Garten                  

 

Da bei der reinen Textsuche kein vector_score berechnet wird, wird als vector_score 0 ausgegeben und der score stimmt mit dem text_score überein. Die ersten beiden Treffer sind Artikel zu barocken Gebäuden in Dresden, für die restlichen Artikel trifft dies aber nicht zu.

Im zweiten Beispiel führen wir eine reine Vektorsuche durch.

 

SELECT scores.text_score, scores.vector_score, scores.score, wp.page_title
FROM JSON_TABLE(
       (SELECT JSON(
           DBMS_HYBRID_VECTOR.SEARCH(
               JSON(
                   '{  "hybrid_index_name"  : "wp_hybrid_idx",
                       "vector":
                           {"search_text"   : "baroque building in Dresden",
                            "search_mode"   : "DOCUMENT",
                            "aggregator"    : "AVG"},
                       "return":
                           {"values"        : [ "rowid", "text_score", "vector_score", "score" ],
                            "topN"          : 6}
                   }'
               )
           )
       )),
       '$[*]' 
       COLUMNS (row_id CHAR(18) PATH '$."rowid"',
                score NUMBER(5,2) PATH '$.score',
                 text_score NUMBER(5,2) PATH '$.text_score',
                 vector_score NUMBER(5,2) PATH '$.vector_score')
    ) scores
    JOIN wikipedia wp ON (scores.row_id = wp.rowid)
ORDER BY scores.score DESC;

TEXT_SCORE    VECTOR_SCORE    SCORE    PAGE_TITLE                   
_____________ _______________ ________ ____________________________ 
0             76.27           76.27    Zwinger (Dresden)            
0             75.14           75.14    Schilling & Graebner     
0             74.61           74.61    Gaetano Chiaveri             
0             74.06           74.06    Augustus II the Strong       
0             73.93           73.93    Palais Flemming-Sulkowski    
0             73.88           73.88    Dresden Panometer            

 

Bei der reinen Vektorsuche ist entsprechend der text_score 0 und der score stimmt mit dem vector_score überein. Bei näherer Betrachtung erkennt man, dass sich nur der erste und fünfte Eintrag auf ein barockes Gebäude in Dresden bezieht.

Im dritten Beispiel führen wir eine hybride Suche (sowohl Text- als auch Vektorsuche) durch.

 

SELECT scores.text_score, scores.vector_score, scores.score, wp.page_title
FROM JSON_TABLE(
       (SELECT JSON(
           DBMS_HYBRID_VECTOR.SEARCH(
               JSON(
                   '{  "hybrid_index_name"  : "wp_hybrid_idx",
                       "text":
                           {"contains"      : "baroque, building"},
                       "vector":
                           {"search_text"   : "baroque building in Dresden",
                            "search_mode"   : "DOCUMENT",
                            "aggregator"    : "AVG"},
                       "return":
                           {"values"        : [ "rowid", "text_score", "vector_score", "score" ],
                            "topN"          : 6}
                   }'
               )
           )
       )),
       '$[*]' 
       COLUMNS (row_id CHAR(18) PATH '$."rowid"',
                score NUMBER(5,2) PATH '$.score',
                 text_score NUMBER(5,2) PATH '$.text_score',
                 vector_score NUMBER(5,2) PATH '$.vector_score')
    ) scores
    JOIN wikipedia wp ON (scores.row_id = wp.rowid)
ORDER BY scores.score DESC;

TEXT_SCORE    VECTOR_SCORE    SCORE    PAGE_TITLE                    
_____________ _______________ ________ _____________________________ 
60            74.3            73       List of Baroque residences    
54            73.29           71.54    Landhaus (Dresden)            
54            72.88           71.16    Japanisches Palais            
8             76.27           70.06    Zwinger (Dresden)             
54            71.35           69.77    Kaiserpalast                  
58            70.59           69.45    Frauenkirche, Dresden        

 

Während der erste Treffer barocke Gebäude weltweit auflistet (darunter auch einige in Dresden) beziehen sich die restlichen Artikel direkt auf Dresdner Gebäude im Barockstil.

 

Zusammenfassung:

Das Beispiel verdeutlicht den Mehrwert der hybriden Suche anschaulich und macht klar, dass die hybride Suche tatsächlich eine deutliche Verbesserung gegenüber der reinen Text- oder Vektorsuche bewirken kann.

Neugierig geworden? Weiterführende Informationen und Beispiele zur Architektur und Nutzung von Vector Search und Einbettungsmodellen finden Sie unserem Praxisworkshop Einführung in Oracle Vector Search.

Kommentare

Keine Kommentare

Kommentar schreiben

* Diese Felder sind erforderlich