| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- import { Injectable, OnModuleInit } from '@nestjs/common';
- import { MongoCoreService } from 'src/mongo/mongo-core.service';
- import { FFBProductionRepository } from 'src/FFB/mongo-ffb-production.repository';
- import { FFBProduction } from '../ffb-production.schema';
- import { GeminiEmbeddingService } from '../gemini-embedding.service';
- @Injectable()
- export class FFBVectorService implements OnModuleInit {
- private repo: FFBProductionRepository;
- constructor(
- private readonly mongoCore: MongoCoreService,
- private readonly embeddingService: GeminiEmbeddingService
- ) { }
- async onModuleInit() {
- // Initialize Mongo repository
- const db = await this.mongoCore.getDb();
- this.repo = new FFBProductionRepository(db);
- await this.repo.init();
- console.log('✅ Gemini embedding service ready. Repository initialized.');
- }
- /** Convert a record to a string suitable for embedding */
- private recordToText(record: FFBProduction): string {
- return `Production on ${new Date(record.productionDate).toISOString()} at ${record.site} in ${record.phase} ${record.block} produced ${record.quantity} ${record.quantityUom} with a total weight of ${record.weight} ${record.weightUom}.`;
- }
- /** Insert a single record with embedding vector */
- async insertWithVector(record: FFBProduction) {
- const text = this.recordToText(record);
- const vector = await this.embeddingService.embedText(text);
- const data: FFBProduction & { vector: number[] } = { ...record, vector };
- return this.repo.create(data);
- }
- /** Search for top-k similar records using a text query */
- async vectorSearch(query: string, k = 5, filter: Record<string, any> = {}) {
- if (!query) throw new Error('Query string cannot be empty');
- const vector = await this.embeddingService.embedText(query);
- const results = await this.repo.vectorSearch(vector, k, 50, filter);
- return results.map((r) => ({
- ...r,
- _id: r._id.toString(),
- score: r.score,
- }));
- }
- /* For traditional operation that requires arithematic operations. */
- async aggregate(pipeline: Array<Record<string, any>>): Promise<any[]> {
- return this.repo.aggregate(pipeline);
- }
- }
|