SeemGen/Services/LocalVectorSearchService.cs

90 lines
2.8 KiB
C#

using BLAIzor.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace BLAIzor.Services
{
public class LocalVectorSearchService
{
//private List<WebPageContent> _cachedContents = new();
//private List<HtmlSnippet> _cachedSnippets = new();
private int _cachedContentVersion = -1;
private int _cachedSnippetVersion = -1;
// Inject any needed services (e.g. DbContext, versioning service)
public LocalVectorSearchService()
{
}
//public void SetContentCache(List<WebPageContent> contents, int contentVersion)
//{
// _cachedContents = contents;
// _cachedContentVersion = contentVersion;
//}
//public void SetSnippetCache(List<HtmlSnippet> snippets, int snippetVersion)
//{
// _cachedSnippets = snippets;
// _cachedSnippetVersion = snippetVersion;
//}
public bool IsContentVersionOutdated(int currentVersion)
=> currentVersion != _cachedContentVersion;
public bool IsSnippetVersionOutdated(int currentVersion)
=> currentVersion != _cachedSnippetVersion;
public List<WebPageContent> SearchContent(float[] queryVector, List<WebPageContent> cachedContents, int maxResults = 5)
{
return cachedContents
.Select(c => new
{
Content = c,
Similarity = CosineSimilarity(queryVector, c.Vectors)
})
.OrderByDescending(x => x.Similarity)
.Take(maxResults)
.Select(x => x.Content)
.ToList();
}
public List<HtmlSnippet> SearchSnippets(float[] queryVector, List<HtmlSnippet> cachedSnippets, int maxResults = 5)
{
return cachedSnippets
.Select(s => new
{
Snippet = s,
Similarity = CosineSimilarity(queryVector, s.Vectors)
})
.OrderByDescending(x => x.Similarity)
.Take(maxResults)
.Select(x => x.Snippet)
.ToList();
}
private float CosineSimilarity(float[] vectorA, float[] vectorB)
{
if (vectorA == null || vectorB == null || vectorA.Length != vectorB.Length)
return 0f;
float dot = 0f, magA = 0f, magB = 0f;
for (int i = 0; i < vectorA.Length; i++)
{
dot += vectorA[i] * vectorB[i];
magA += vectorA[i] * vectorA[i];
magB += vectorB[i] * vectorB[i];
}
if (magA == 0 || magB == 0)
return 0f;
return dot / ((float)Math.Sqrt(magA) * (float)Math.Sqrt(magB));
}
}
}