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
