90 lines
2.8 KiB
C#
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));
|
|
}
|
|
}
|
|
}
|
|
|
|
|