添加注释添加项目文件。
This commit is contained in:
14
MilvusDemo/MilvusDemo.csproj
Normal file
14
MilvusDemo/MilvusDemo.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Milvus.Client" Version="2.3.0-preview.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
144
MilvusDemo/MilvusService.cs
Normal file
144
MilvusDemo/MilvusService.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Milvus.Client;
|
||||
|
||||
namespace MilvusDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供与Milvus向量数据库交互的服务类
|
||||
/// </summary>
|
||||
public class MilvusService
|
||||
{
|
||||
private readonly MilvusClient _milvusClient;
|
||||
private readonly string _collectionName;
|
||||
private readonly int _dim;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化MilvusService的新实例
|
||||
/// </summary>
|
||||
/// <param name="host">Milvus服务器主机名</param>
|
||||
/// <param name="port">Milvus服务器端口</param>
|
||||
/// <param name="collectionName">集合名称</param>
|
||||
/// <param name="dim">向量维度</param>
|
||||
public MilvusService(string host, int port, string collectionName, int dim)
|
||||
{
|
||||
_milvusClient = new MilvusClient(host, port);
|
||||
_collectionName = collectionName;
|
||||
_dim = dim;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化集合,如果存在则删除并重新创建
|
||||
/// </summary>
|
||||
public async Task InitializeCollectionAsync()
|
||||
{
|
||||
// 检查集合是否存在,如果存在则删除
|
||||
if (await _milvusClient.HasCollectionAsync(_collectionName))
|
||||
{
|
||||
var collectionToDrop = _milvusClient.GetCollection(_collectionName);
|
||||
await collectionToDrop.DropAsync();
|
||||
Console.WriteLine($"Collection '{_collectionName}' dropped.");
|
||||
}
|
||||
|
||||
// 创建新的集合
|
||||
await _milvusClient.CreateCollectionAsync(
|
||||
_collectionName,
|
||||
new[]
|
||||
{
|
||||
FieldSchema.Create<long>("id", isPrimaryKey: true),
|
||||
FieldSchema.CreateVarchar("varchar", 256),
|
||||
FieldSchema.CreateFloatVector("vector", _dim)
|
||||
});
|
||||
Console.WriteLine($"Collection '{_collectionName}' created.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建索引并加载集合
|
||||
/// </summary>
|
||||
public async Task CreateIndexAndLoadAsync()
|
||||
{
|
||||
var collection = _milvusClient.GetCollection(_collectionName);
|
||||
|
||||
// 创建索引
|
||||
await collection.CreateIndexAsync("vector", IndexType.Flat, SimilarityMetricType.L2);
|
||||
Console.WriteLine("Index created.");
|
||||
|
||||
// 加载集合
|
||||
await collection.LoadAsync();
|
||||
Console.WriteLine("Collection loaded.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插入随机向量数据
|
||||
/// </summary>
|
||||
/// <param name="count">要插入的向量数量</param>
|
||||
public async Task InsertRandomDataAsync(int count)
|
||||
{
|
||||
var collection = _milvusClient.GetCollection(_collectionName);
|
||||
var random = new Random();
|
||||
|
||||
// 生成随机向量
|
||||
var vectors = new List<ReadOnlyMemory<float>>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var vector = new float[_dim];
|
||||
for (int j = 0; j < _dim; j++)
|
||||
{
|
||||
vector[j] = (float)random.NextDouble();
|
||||
}
|
||||
vectors.Add(vector);
|
||||
}
|
||||
|
||||
// 生成ID和字符串字段
|
||||
var ids = Enumerable.Range(0, count).Select(i => (long)i).ToList();
|
||||
var varchars = ids.Select(i => $"varchar_{i}").ToList();
|
||||
|
||||
// 打包数据
|
||||
var insertData = new List<FieldData>
|
||||
{
|
||||
FieldData.Create("id", ids),
|
||||
FieldData.Create("varchar", varchars),
|
||||
FieldData.CreateFloatVector("vector", vectors)
|
||||
};
|
||||
|
||||
// 执行插入
|
||||
await collection.InsertAsync(insertData);
|
||||
Console.WriteLine("Data inserted.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行向量相似度搜索
|
||||
/// </summary>
|
||||
/// <param name="topK">返回最相似的结果数量</param>
|
||||
/// <returns>搜索结果</returns>
|
||||
public async Task<SearchResults> SearchVectorAsync(int topK = 5)
|
||||
{
|
||||
var collection = _milvusClient.GetCollection(_collectionName);
|
||||
var random = new Random();
|
||||
|
||||
// 生成随机目标向量
|
||||
var targetVector = new float[_dim];
|
||||
for (int j = 0; j < _dim; j++)
|
||||
{
|
||||
targetVector[j] = (float)random.NextDouble();
|
||||
}
|
||||
|
||||
// 设置搜索参数
|
||||
var searchParameters = new SearchParameters();
|
||||
searchParameters.OutputFields.Add("id");
|
||||
searchParameters.OutputFields.Add("varchar");
|
||||
|
||||
// 执行搜索
|
||||
var searchResults = await collection.SearchAsync(
|
||||
"vector",
|
||||
new[] { (ReadOnlyMemory<float>)targetVector },
|
||||
SimilarityMetricType.L2,
|
||||
topK,
|
||||
searchParameters);
|
||||
|
||||
return searchResults;
|
||||
}
|
||||
}
|
||||
}
|
||||
125
MilvusDemo/MilvusServiceTests.cs
Normal file
125
MilvusDemo/MilvusServiceTests.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Milvus.Client;
|
||||
|
||||
namespace MilvusDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于测试MilvusService的模拟类
|
||||
/// </summary>
|
||||
public class MilvusServiceTests
|
||||
{
|
||||
// 模拟的MilvusService实例
|
||||
private readonly MilvusService _milvusService;
|
||||
|
||||
// 标记各个方法是否被调用
|
||||
public bool InitializeCollectionCalled { get; private set; }
|
||||
public bool CreateIndexAndLoadCalled { get; private set; }
|
||||
public bool InsertRandomDataCalled { get; private set; }
|
||||
public bool SearchVectorCalled { get; private set; }
|
||||
|
||||
// 记录传入的参数
|
||||
public int InsertDataCount { get; private set; }
|
||||
public int SearchTopK { get; private set; }
|
||||
|
||||
public MilvusServiceTests()
|
||||
{
|
||||
// 创建真实的MilvusService实例,但我们将拦截其方法调用
|
||||
_milvusService = new MilvusService("localhost", 19530, "test_collection", 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模拟初始化集合的方法
|
||||
/// </summary>
|
||||
public async Task MockInitializeCollectionAsync()
|
||||
{
|
||||
InitializeCollectionCalled = true;
|
||||
Console.WriteLine("[TEST] InitializeCollectionAsync called");
|
||||
|
||||
// 模拟操作延迟
|
||||
await Task.Delay(100);
|
||||
|
||||
Console.WriteLine("[TEST] Collection dropped and created");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模拟创建索引并加载集合的方法
|
||||
/// </summary>
|
||||
public async Task MockCreateIndexAndLoadAsync()
|
||||
{
|
||||
CreateIndexAndLoadCalled = true;
|
||||
Console.WriteLine("[TEST] CreateIndexAndLoadAsync called");
|
||||
|
||||
// 模拟操作延迟
|
||||
await Task.Delay(100);
|
||||
|
||||
Console.WriteLine("[TEST] Index created");
|
||||
Console.WriteLine("[TEST] Collection loaded");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模拟插入随机数据的方法
|
||||
/// </summary>
|
||||
public async Task MockInsertRandomDataAsync(int count)
|
||||
{
|
||||
InsertRandomDataCalled = true;
|
||||
InsertDataCount = count;
|
||||
Console.WriteLine($"[TEST] InsertRandomDataAsync called with count: {count}");
|
||||
|
||||
// 模拟操作延迟
|
||||
await Task.Delay(100);
|
||||
|
||||
Console.WriteLine("[TEST] Data inserted");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模拟向量搜索的方法
|
||||
/// </summary>
|
||||
public async Task<SearchResults> MockSearchVectorAsync(int topK = 5)
|
||||
{
|
||||
SearchVectorCalled = true;
|
||||
SearchTopK = topK;
|
||||
Console.WriteLine($"[TEST] SearchVectorAsync called with topK: {topK}");
|
||||
|
||||
// 模拟操作延迟
|
||||
await Task.Delay(100);
|
||||
|
||||
// 创建模拟的搜索结果
|
||||
var mockIds = new List<long>();
|
||||
for (int i = 0; i < topK; i++)
|
||||
{
|
||||
mockIds.Add(1000 + i); // 使用1000+i作为模拟ID
|
||||
}
|
||||
|
||||
Console.WriteLine("[TEST] Search completed");
|
||||
|
||||
// 注意:这里我们无法直接创建SearchResults实例,因为它可能是内部类
|
||||
// 在实际测试中,您可能需要使用模拟框架如Moq来模拟这个返回值
|
||||
// 这里我们返回null,实际使用时需要处理这种情况
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 运行完整的测试流程
|
||||
/// </summary>
|
||||
public async Task RunFullTestAsync()
|
||||
{
|
||||
Console.WriteLine("=== Starting MilvusService Test ===");
|
||||
|
||||
await MockInitializeCollectionAsync();
|
||||
await MockCreateIndexAndLoadAsync();
|
||||
await MockInsertRandomDataAsync(1000);
|
||||
await MockSearchVectorAsync(5);
|
||||
|
||||
// 打印测试结果摘要
|
||||
Console.WriteLine("\n=== Test Summary ===");
|
||||
Console.WriteLine($"InitializeCollection Called: {InitializeCollectionCalled}");
|
||||
Console.WriteLine($"CreateIndexAndLoad Called: {CreateIndexAndLoadCalled}");
|
||||
Console.WriteLine($"InsertRandomData Called: {InsertRandomDataCalled} (Count: {InsertDataCount})");
|
||||
Console.WriteLine($"SearchVector Called: {SearchVectorCalled} (TopK: {SearchTopK})");
|
||||
|
||||
Console.WriteLine("=== Test Completed ===");
|
||||
}
|
||||
}
|
||||
}
|
||||
74
MilvusDemo/Program.cs
Normal file
74
MilvusDemo/Program.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MilvusDemo
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Milvus 演示程序");
|
||||
Console.WriteLine("1. 运行实际的 Milvus 操作");
|
||||
Console.WriteLine("2. 运行模拟测试");
|
||||
Console.Write("请选择 (1/2): ");
|
||||
|
||||
string choice = Console.ReadLine();
|
||||
|
||||
if (choice == "2")
|
||||
{
|
||||
await RunTests();
|
||||
}
|
||||
else
|
||||
{
|
||||
await RunActualMilvusOperations();
|
||||
}
|
||||
}
|
||||
|
||||
static async Task RunActualMilvusOperations()
|
||||
{
|
||||
// 初始化MilvusService
|
||||
const string host = "localhost";
|
||||
const int port = 19530;
|
||||
const string collectionName = "csharp_demo_collection";
|
||||
const int dim = 8; // 向量维度
|
||||
|
||||
// 创建MilvusService实例
|
||||
var milvusService = new MilvusService(host, port, collectionName, dim);
|
||||
|
||||
try
|
||||
{
|
||||
// 初始化集合(如果存在则删除并重新创建)
|
||||
await milvusService.InitializeCollectionAsync();
|
||||
|
||||
// 创建索引并加载集合
|
||||
await milvusService.CreateIndexAndLoadAsync();
|
||||
|
||||
// 插入随机数据
|
||||
await milvusService.InsertRandomDataAsync(1000);
|
||||
|
||||
// 执行向量搜索
|
||||
var searchResults = await milvusService.SearchVectorAsync(5);
|
||||
|
||||
// 显示搜索结果
|
||||
Console.WriteLine("\nSearch results:");
|
||||
foreach (var result in searchResults.Ids.LongIds)
|
||||
{
|
||||
Console.WriteLine($"- ID: {result}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error: {ex.Message}");
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
Console.WriteLine($"Inner error: {ex.InnerException.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async Task RunTests()
|
||||
{
|
||||
await TestRunner.RunTests();
|
||||
}
|
||||
}
|
||||
}
|
||||
24
MilvusDemo/TestRunner.cs
Normal file
24
MilvusDemo/TestRunner.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MilvusDemo
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于运行MilvusService测试的类
|
||||
/// </summary>
|
||||
public class TestRunner
|
||||
{
|
||||
/// <summary>
|
||||
/// 运行测试
|
||||
/// </summary>
|
||||
public static async Task RunTests()
|
||||
{
|
||||
Console.WriteLine("开始运行MilvusService测试...");
|
||||
|
||||
var tester = new MilvusServiceTests();
|
||||
await tester.RunFullTestAsync();
|
||||
|
||||
Console.WriteLine("测试完成!");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user