hugging2021/local-gemma4-rag
1
1import { create, insert, search, removeMultiple } from 'https://cdn.jsdelivr.net/npm/@orama/orama@latest/+esm';2 3export class VectorDB {4 constructor() {5 this.db = null;6 this.isInitialized = false;7 }8 9 async init() {10 if (this.isInitialized) return;11 12 this.db = await create({13 schema: {14 text: 'string',15 fileName: 'string',16 embedding: 'vector[384]', // MiniLM-L6-v2 dimension17 },18 indexStyles: {19 embedding: 'cosine', // Recommended for normalized embeddings20 },21 });22 23 this.isInitialized = true;24 console.log('๐ฆ Orama Vector DB initialized');25 }26 27 async addDocument(text, fileName, embedding) {28 if (!this.isInitialized) await this.init();29 30 return await insert(this.db, {31 text,32 fileName,33 embedding,34 });35 }36 37 async removeDocumentsByFileName(fileName) {38 if (!this.isInitialized) await this.init();39 40 // 1. Search for all documents with this filename41 const results = await search(this.db, {42 where: {43 fileName: fileName44 },45 limit: 1000 // A single file likely won't have more than 1000 chunks46 });47 48 const ids = results.hits.map(hit => hit.id);49 if (ids.length > 0) {50 await removeMultiple(this.db, ids);51 console.log(`๐๏ธ Removed ${ids.length} chunks for ${fileName}`);52 }53 return ids.length;54 }55 56 async query(vector, limit = 5) {57 if (!this.isInitialized) await this.init();58 59 const results = await search(this.db, {60 mode: 'vector',61 vector: {62 value: vector,63 property: 'embedding',64 },65 similarity: 0.5,66 limit: limit,67 });68 69 return results.hits.map(hit => ({70 text: hit.document.text,71 fileName: hit.document.fileName,72 score: hit.score,73 }));74 }75 76 async clear() {77 this.isInitialized = false;78 await this.init();79 }80}81 82// Singleton instance83export const db = new VectorDB();84 