Python使用Oracle向量數(shù)據(jù)庫(kù)實(shí)現(xiàn)文本檢索系統(tǒng)
代碼分析
讓我們逐步分析原始代碼的主要組件和功能:
導(dǎo)入必要的庫(kù):
- 使用
oracledb連接Oracle數(shù)據(jù)庫(kù) - 使用
numpy處理向量 - 使用
pydantic進(jìn)行配置驗(yàn)證 - 使用
flask和redis進(jìn)行Web應(yīng)用程序集成
- 使用
定義
OracleVectorConfig類:- 使用Pydantic模型驗(yàn)證Oracle連接配置
創(chuàng)建
OracleVector類:- 實(shí)現(xiàn)向量數(shù)據(jù)庫(kù)的核心功能
- 使用
contextmanager管理數(shù)據(jù)庫(kù)連接 - 實(shí)現(xiàn)CRUD操作和向量搜索
實(shí)現(xiàn)
OracleVectorFactory類:- 用于初始化向量數(shù)據(jù)庫(kù)實(shí)例
現(xiàn)在,讓我們基于相同的技術(shù)創(chuàng)建一個(gè)新的示例代碼:
import array
import json
import uuid
from contextlib import contextmanager
from typing import List, Dict, Any
import numpy as np
import oracledb
from pydantic import BaseModel, validator
class OracleConfig(BaseModel):
host: str
port: int
user: str
password: str
database: str
@validator('host', 'user', 'password', 'database')
def check_not_empty(cls, v):
if not v:
raise ValueError("Field cannot be empty")
return v
class TextEmbeddingStore:
def __init__(self, config: OracleConfig):
self.pool = self._create_connection_pool(config)
self.table_name = "text_embeddings"
self._create_table()
def _create_connection_pool(self, config: OracleConfig):
return oracledb.create_pool(
user=config.user,
password=config.password,
dsn=f"{config.host}:{config.port}/{config.database}",
min=1,
max=5,
increment=1
)
@contextmanager
def _get_cursor(self):
conn = self.pool.acquire()
conn.inputtypehandler = self._input_type_handler
conn.outputtypehandler = self._output_type_handler
cur = conn.cursor()
try:
yield cur
finally:
cur.close()
conn.commit()
conn.close()
def _input_type_handler(self, cursor, value, arraysize):
if isinstance(value, np.ndarray):
return cursor.var(
oracledb.DB_TYPE_VECTOR,
arraysize=arraysize,
inconverter=self._numpy_to_array
)
def _output_type_handler(self, cursor, metadata):
if metadata.type_code is oracledb.DB_TYPE_VECTOR:
return cursor.var(
metadata.type_code,
arraysize=cursor.arraysize,
outconverter=self._array_to_numpy
)
def _numpy_to_array(self, value):
return array.array('f', value)
def _array_to_numpy(self, value):
return np.array(value, dtype=np.float32)
def _create_table(self):
with self._get_cursor() as cur:
cur.execute(f"""
CREATE TABLE IF NOT EXISTS {self.table_name} (
id VARCHAR2(100) PRIMARY KEY,
text CLOB NOT NULL,
metadata JSON,
embedding VECTOR NOT NULL
)
""")
def add_texts(self, texts: List[str], embeddings: List[List[float]], metadata: List[Dict] = None):
if metadata is None:
metadata = [{} for _ in texts]
values = [
(str(uuid.uuid4()), text, json.dumps(meta), np.array(emb, dtype=np.float32))
for text, emb, meta in zip(texts, embeddings, metadata)
]
with self._get_cursor() as cur:
cur.executemany(
f"INSERT INTO {self.table_name} (id, text, metadata, embedding) VALUES (:1, :2, :3, :4)",
values
)
def search_similar(self, query_vector: List[float], top_k: int = 5) -> List[Dict[str, Any]]:
query_vector = np.array(query_vector, dtype=np.float32)
with self._get_cursor() as cur:
cur.execute(
f"""
SELECT id, text, metadata, vector_distance(embedding, :1) AS distance
FROM {self.table_name}
ORDER BY distance
FETCH FIRST :2 ROWS ONLY
""",
[query_vector, top_k]
)
results = []
for id, text, metadata, distance in cur:
results.append({
"id": id,
"text": text,
"metadata": json.loads(metadata),
"distance": distance,
"similarity": 1 - distance
})
return results
# 使用示例
if __name__ == "__main__":
config = OracleConfig(
host="localhost",
port=1521,
user="your_username",
password="your_password",
database="your_database"
)
store = TextEmbeddingStore(config)
# 添加文本和嵌入
texts = ["Hello world", "Python programming", "Vector database"]
embeddings = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]
store.add_texts(texts, embeddings)
# 搜索相似文本
query_vector = [0.2, 0.3, 0.4]
results = store.search_similar(query_vector, top_k=2)
for result in results:
print(f"Text: {result['text']}")
print(f"Similarity: {result['similarity']:.4f}")
print("---")
這個(gè)新的示例代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)化版的文本嵌入存儲(chǔ)系統(tǒng),使用Oracle向量數(shù)據(jù)庫(kù)。它包含以下主要功能:
- 使用Pydantic進(jìn)行配置驗(yàn)證
- 創(chuàng)建和管理Oracle連接池
- 使用上下文管理器處理數(shù)據(jù)庫(kù)連接
- 處理numpy數(shù)組和Oracle向量類型之間的轉(zhuǎn)換
- 實(shí)現(xiàn)添加文本和嵌入的方法
- 實(shí)現(xiàn)基于向量相似度的搜索方法
這個(gè)示例展示了如何使用Oracle向量數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)和檢索文本嵌入,可以作為構(gòu)建更復(fù)雜的文本檢索或推薦系統(tǒng)的基礎(chǔ)。
在實(shí)際應(yīng)用中,你可能需要添加錯(cuò)誤處理、日志記錄、性能優(yōu)化等功能。
到此這篇關(guān)于Python使用Oracle向量數(shù)據(jù)庫(kù)實(shí)現(xiàn)文本檢索系統(tǒng)的文章就介紹到這了,更多相關(guān)Python Oracle文本檢索系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TensorFlow設(shè)置日志級(jí)別的幾種方式小結(jié)
今天小編就為大家分享一篇TensorFlow設(shè)置日志級(jí)別的幾種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
python中requests庫(kù)+xpath+lxml簡(jiǎn)單使用
這篇文章主要介紹了python中requests庫(kù)+xpath+lxml簡(jiǎn)單使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Python數(shù)據(jù)結(jié)構(gòu)之棧詳解
棧和隊(duì)列是在程序設(shè)計(jì)中常見(jiàn)的數(shù)據(jù)類型,從數(shù)據(jù)結(jié)構(gòu)的角度來(lái)講,棧和隊(duì)列也是線性表,是操作受限的線性表。本文將詳細(xì)介紹一下Python中的棧,感興趣的可以了解一下2022-03-03
使用Python來(lái)做一個(gè)屏幕錄制工具的操作代碼
本文給大家分享使用Python來(lái)做一個(gè)屏幕錄制工具,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01

