LitReviewAI / src /vector_store.py
bano1's picture
Update src/vector_store.py
c2bd4e0 verified
Raw
History Blame Contribute Delete
3.75 kB
import faiss
import numpy as np
import pickle
import os
class VectorStore:
def __init__(
self,
index_path="data/vector.index",
docs_path="data/documents.pkl"
):
self.index = None
self.documents = []
self.index_path = index_path
self.docs_path = docs_path
# Load existing database
self.load()
# =====================================================
# BUILD VECTOR DATABASE
# =====================================================
def build(
self,
embeddings,
documents
):
"""
Create FAISS vector database.
embeddings:
SentenceTransformer embeddings
documents:
text chunks
"""
if len(embeddings) == 0:
return
embeddings = np.array(
embeddings
).astype("float32")
# Normalize for cosine similarity
faiss.normalize_L2(
embeddings
)
dimension = embeddings.shape[1]
# Cosine similarity search
self.index = faiss.IndexFlatIP(
dimension
)
self.index.add(
embeddings
)
self.documents = documents
self.save()
# =====================================================
# SEARCH
# =====================================================
def search(
self,
query_embedding,
k=5
):
if self.index is None:
return []
query_embedding = np.array(
[query_embedding]
).astype("float32")
faiss.normalize_L2(
query_embedding
)
distances, indices = self.index.search(
query_embedding,
k
)
results = []
for score, idx in zip(
distances[0],
indices[0]
):
if idx != -1:
results.append(
self.documents[idx]
)
return results
# =====================================================
# SAVE DATABASE
# =====================================================
def save(self):
"""
Save FAISS index + documents.
Creates folders automatically.
"""
# Create directories if missing
index_dir = os.path.dirname(
self.index_path
)
docs_dir = os.path.dirname(
self.docs_path
)
if index_dir:
os.makedirs(
index_dir,
exist_ok=True
)
if docs_dir:
os.makedirs(
docs_dir,
exist_ok=True
)
# Save FAISS index
if self.index is not None:
faiss.write_index(
self.index,
self.index_path
)
# Save documents
with open(
self.docs_path,
"wb"
) as f:
pickle.dump(
self.documents,
f
)
# =====================================================
# LOAD DATABASE
# =====================================================
def load(self):
"""
Load FAISS database if available.
"""
if os.path.exists(
self.index_path
):
self.index = faiss.read_index(
self.index_path
)
if os.path.exists(
self.docs_path
):
with open(
self.docs_path,
"rb"
) as f:
self.documents = pickle.load(f)