/** * BM25 (Best Matching 25) Implementation * * A ranking function for keyword-based search. This is a pure domain service * with no external dependencies - just algorithms operating on data. * * BM25 estimates relevance of documents to a search query using term frequency * and inverse document frequency with length normalization. */ /** * Tokenize text into normalized terms. * * @param text - Text to tokenize * @returns Array of lowercase tokens */ export declare function tokenize(text: string): string[]; /** * Document data for BM25 scoring. */ export interface BM25Document { id: string; content: string; /** Pre-computed tokens (optional, computed from content if not provided) */ tokens?: string[]; } /** * BM25 search result. */ export interface BM25Result { id: string; score: number; } /** * BM25 search index. * * This is a pure in-memory data structure with no I/O operations. * Build the index by adding documents, then search against it. */ export declare class BM25Index { private documents; private avgDocLength; private documentFrequencies; private totalDocs; /** * Add documents to the index. * * @param documents - Array of documents to index */ addDocuments(documents: BM25Document[]): void; /** * Calculate IDF (Inverse Document Frequency) for a term. */ private idf; /** * IDF for a term in this index (same formula as BM25 scoring). * Returns 0 if the term does not appear in any indexed document. */ getInverseDocumentFrequency(term: string): number; /** * Calculate BM25 score for a document given query terms. */ private score; /** * Search the index with a query. * * @param query - Search query * @param topK - Maximum number of results to return * @returns Sorted array of results (highest score first) */ search(query: string, topK?: number): BM25Result[]; /** * Get the number of indexed documents. */ get size(): number; /** * Clear the index. */ clear(): void; /** * Add a single document by ID and pre-computed tokens. * * @param id - Document identifier * @param tokens - Pre-computed tokens */ addDocument(id: string, tokens: string[]): void; /** * Remove a document from the index. * Updates document frequencies and average document length. * * @param id - Document identifier to remove * @returns true if document was removed, false if not found */ removeDocument(id: string): boolean; /** * Update a document in the index (remove + add). * More efficient than separate remove/add as it batches the operations. * * @param id - Document identifier * @param newTokens - New tokens for the document */ updateDocument(id: string, newTokens: string[]): void; /** * Check if a document exists in the index. * * @param id - Document identifier * @returns true if document exists */ hasDocument(id: string): boolean; /** * Serialize the index to a JSON-compatible object. */ serialize(): BM25SerializedData; /** * Deserialize a BM25 index from saved data. */ static deserialize(data: BM25SerializedData): BM25Index; } /** * Serialized BM25 index data. */ export interface BM25SerializedData { documents: Record; avgDocLength: number; documentFrequencies: Record; totalDocs: number; } /** * Normalize a raw score to 0-1 range using sigmoid function. * * @param score - Raw score * @param midpoint - Score at which output is 0.5 * @returns Normalized score between 0 and 1 */ export declare function normalizeScore(score: number, midpoint?: number): number;