diff --git a/CodeBase/CodeBase.csproj b/CodeBase/CodeBase.csproj
index 8718518..cd5424c 100644
--- a/CodeBase/CodeBase.csproj
+++ b/CodeBase/CodeBase.csproj
@@ -10,6 +10,7 @@
+
diff --git a/CodeBase/Program.cs b/CodeBase/Program.cs
index cb2d15a..c583cda 100644
--- a/CodeBase/Program.cs
+++ b/CodeBase/Program.cs
@@ -1,9 +1,12 @@
using CodeBase.Services;
using CodeBase.Warehouse;
+using Qdrant.Client;
+using Qdrant.Client.Grpc;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
+builder.Services.AddSingleton(new QdrantClient("localhost", 6334));
builder.Services.AddSingleton();
builder.Services.AddTransient();
@@ -11,6 +14,7 @@ builder.Services.AddTransient();
builder.Services.AddScoped();
builder.Services.AddTransient();
builder.Services.AddTransient();
+builder.Services.AddTransient();
builder.Services.AddControllers();
builder.Services.AddSwaggerGen();
@@ -30,4 +34,27 @@ app.UseAuthorization();
app.MapControllers();
+
+using (var scope = app.Services.CreateScope())
+{
+ var qdrantClient = scope.ServiceProvider.GetRequiredService();
+
+ // Получаем список существующих коллекций
+ var collections = await qdrantClient.ListCollectionsAsync();
+
+ if (!collections.Contains("CodeBaseCollection"))
+ {
+ Console.WriteLine("Создаем новую коллекцию в Qdrant...");
+ await qdrantClient.CreateCollectionAsync(
+ collectionName: "CodeBaseCollection",
+ vectorsConfig: new VectorParams
+ {
+ Size = 768, // Размер вектора GraphCodeBERT
+ Distance = Distance.Cosine // Сразу задаем алгоритм поиска (косинусное сходство)
+ }
+ );
+ }
+}
+
+
app.Run();
diff --git a/CodeBase/Repositories/QdrantRepository.cs b/CodeBase/Repositories/QdrantRepository.cs
new file mode 100644
index 0000000..7db4408
--- /dev/null
+++ b/CodeBase/Repositories/QdrantRepository.cs
@@ -0,0 +1,89 @@
+using CodeBase.Models;
+using Qdrant.Client;
+using Qdrant.Client.Grpc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+public class QdrantRepository
+{
+ private readonly QdrantClient _client;
+ private const string CollectionName = "CodeBaseCollection";
+
+ public QdrantRepository(QdrantClient client)
+ {
+ _client = client;
+ }
+
+ // ==========================================
+ // 1. СОХРАНЕНИЕ ВЕКТОРОВ С ПРИВЯЗКОЙ К ПРОЕКТУ
+ // ==========================================
+ public async Task SaveChunksAsync(string projectName, List chunks)
+ {
+ var points = new List();
+
+ foreach (var chunk in chunks)
+ {
+ if (chunk.Vector == null) continue;
+
+ // Формируем точку для БД
+ var point = new PointStruct
+ {
+ Id = Guid.NewGuid(), // Уникальный ID чанка
+ Vectors = chunk.Vector, // Тот самый массив float[]
+
+ // Вот здесь мы навешиваем все ярлыки!
+ Payload =
+ {
+ ["ProjectName"] = projectName,
+ ["FilePath"] = chunk.FilePath,
+ ["MethodName"] = chunk.MethodName,
+ ["Content"] = chunk.Content // Сам текст кода тоже храним прямо в БД
+ }
+ };
+ points.Add(point);
+ }
+
+ // Отправляем пачку векторов в базу
+ await _client.UpsertAsync(CollectionName, points);
+ }
+
+ // ==========================================
+ // 2. ПОИСК ТОЛЬКО В РАМКАХ ОДНОГО ПРОЕКТА
+ // ==========================================
+ public async Task> SearchAsync(string projectName, float[] queryVector, int topK = 15)
+ {
+ // Создаем фильтр: искать только там, где ProjectName совпадает с запрошенным
+ var projectFilter = new Filter
+ {
+ Must = {
+ new Condition
+ {
+ Field = new FieldCondition
+ {
+ Key = "ProjectName",
+ Match = new Match { Keyword = projectName }
+ }
+ }
+ }
+ };
+
+ // База делает всю тяжелую математику за нас!
+ var searchResults = await _client.SearchAsync(
+ collectionName: CollectionName,
+ vector: queryVector,
+ limit: (ulong)topK,
+ filter: projectFilter, // Передаем наш фильтр
+ payloadSelector: true // Просим БД вернуть Payload вместе с результатами
+ );
+
+ // Превращаем ответы базы обратно в наши C#-объекты CodeChunk
+ return searchResults.Select(hit => new CodeChunk
+ {
+ FilePath = hit.Payload["FilePath"].StringValue,
+ MethodName = hit.Payload["MethodName"].StringValue,
+ Content = hit.Payload["Content"].StringValue
+ }).ToList();
+ }
+}
\ No newline at end of file
diff --git a/CodeBase/Services/CodeService.cs b/CodeBase/Services/CodeService.cs
index c381a59..415d34e 100644
--- a/CodeBase/Services/CodeService.cs
+++ b/CodeBase/Services/CodeService.cs
@@ -4,7 +4,7 @@ using CodeBase.Warehouse;
namespace CodeBase.Services
{
public class CodeService(ChunkService service,
- ChunkWarehouse warehouse,
+ QdrantRepository repository,
VectorizationService vectorizationService,
LlmService llmService)
{
@@ -32,7 +32,7 @@ namespace CodeBase.Services
var chunks = await vectorizationService.EnrichChunksWithVectorsAsync(allChunks);
- warehouse.UpsertDictionary(name, allChunks);
+ await repository.SaveChunksAsync(name, chunks);
return chunks;
}
@@ -41,38 +41,22 @@ namespace CodeBase.Services
{
var query = await vectorizationService.GetVectorAsync(question);
- var answerVectors = Search(query, name, 15);
+ var answerVectors = await SearchAsync(query, name, 15);
- var answer = await llmService.AskQuestionAsync(question, answerVectors.Select(s => s.Chunk).ToList());
+ var answer = await llmService.AskQuestionAsync(question, answerVectors);
return answer;
}
// Главный метод поиска
- public List<(CodeChunk Chunk, float Score)> Search(
+ public async Task> SearchAsync(
float[] queryVector,
string name,
int topK = 3) // Возвращаем топ-3 результата
{
- var memoryBase = warehouse.GetChunks(name);
+ var results = await repository.SearchAsync(name, queryVector, topK);
- var results = new List<(CodeChunk, float)>();
-
- foreach (var chunk in memoryBase)
- {
- if (chunk.Vector == null || chunk.Vector.Length == 0)
- continue;
-
- // Считаем близость вектора вопроса к вектору кода
- float similarity = CalculateCosineSimilarity(queryVector, chunk.Vector);
- results.Add((chunk, similarity));
- }
-
- // Сортируем по убыванию сходства (чем ближе к 1, тем лучше)
- return results
- .OrderByDescending(x => x.Item2)
- .Take(topK)
- .ToList();
+ return results;
}
// Математика косинусного сходства
diff --git a/PythonProject/.idea/vcs.xml b/PythonProject/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/PythonProject/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file