从内存到 ES:.NET 企业级向量检索架构演进之路

CSDN 技术教程系列:文本与向量检索实战(.NET C# 体系)

系列主题:从内存到 Elasticsearch ------ .NET C# 体系下的文本、向量检索技术演进与应用实例教程

目标读者:中高级 .NET 后端开发工程师、AI应用开发者、技术架构师

技术栈:.NET 8/9、C# 12、ONNX Runtime、BGE-M3、CLIP、Elasticsearch、Python Flask


📚 文章系列规划(共5篇)

序号 文章标题 核心技术
1 [BGE-M3 多语言向量模型实战:.NET C# 从原理到落地](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) BGE-M3、ONNX Runtime、Tokenizer
2 [内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) 内存计算、读写锁、并行检索
3 [Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) ES 8.x、Dense Vector、Hybrid Search
4 [CLIP 多模态搜索实战:.NET + Python 跨语言图片检索](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) OpenCLIP、Python Flask、跨模态
5 [从内存到 ES:.NET 企业级向量检索架构演进之路](# 从原理到落地 BGE-M3、ONNX Runtime、Tokenizer 2 内存向量检索引擎设计与实现:C# 轻量级 Milvus 替代方案 内存计算、读写锁、并行检索 3 Elasticsearch 语义搜索实战:.NET 向量+关键词混合检索 ES 8.x、Dense Vector、Hybrid Search 4 CLIP 多模态搜索实战:.NET + Python 跨语言图片检索 OpenCLIP、Python Flask、跨模态 5 从内存到 ES:.NET 企业级向量检索架构演进之路 架构设计、性能优化、容灾策略) 架构设计、性能优化、容灾策略

文章5:从内存到 ES:.NET 企业级向量检索架构演进之路

📝 文章信息

  • 分类:系统架构 / 技术演进 / 企业级应用 / .NET

  • 标签架构设计, 向量检索, 性能优化, 容灾, .NET, C#

📖 章节大纲

1. 引言:架构演进的驱动力
  • 业务增长带来的挑战

  • 技术选型的权衡

2. 阶段一:内存向量检索(C# 实现)
复制代码
┌─────────────┐     ┌──────────────────┐     ┌─────────────┐
│   Client    │────▶│  .NET API (C#)   │────▶│   SQL DB    │
└─────────────┘     │                  │     │  (主数据)    │
                    │  ┌────────────┐  │     └─────────────┘
                    │  │ C# 内存向量 │  │
                    │  │ 存储实现    │  │
                    │  │ (1024-dim) │  │
                    │  └────────────┘  │
                    └──────────────────┘
3. 阶段二:多模型并存(.NET + Python)
复制代码
┌─────────────┐     ┌──────────────────────────────────────────┐
│   Client    │────▶│              .NET API (C#)                │
└─────────────┘     │                                          │
                    │  ┌─────────────┐    ┌─────────────────┐  │
                    │  │ C# BGE-M3   │    │ C# CLIP 向量库   │  │
                    │  │ 内存向量库   │    │ (512-dim)       │  │
                    │  │ (1024-dim)  │    │                 │  │
                    │  └─────────────┘    └─────────────────┘  │
                    │                                          │
                    │  ┌─────────────────────────────────────┐ │
                    │  │        C# 查询策略路由               │ │
                    │  └─────────────────────────────────────┘ │
                    └──────────────────────────────────────────┘
                                        │
                    ┌───────────────────┼───────────────────┐
                    ▼                   ▼                   ▼
              ┌─────────┐        ┌──────────┐        ┌──────────┐
              │ SQL DB  │        │ Python   │        │Elasticsearch│
              │(主数据)  │        │ CLIP服务 │        │ (引入)   │
              └─────────┘        └──────────┘        └──────────┘
4. 阶段三:Elasticsearch 中心化
复制代码
┌─────────────┐     ┌──────────────────────────────────────────┐
│   Client    │────▶│              .NET API (C#)                │
└─────────────┘     │                                          │
                    │  ┌─────────────────────────────────────┐ │
                    │  │      C# 统一查询接口(优先ES)        │ │
                    │  └─────────────────────────────────────┘ │
                    └──────────────────────────────────────────┘
                                        │
                                        ▼
                    ┌──────────────────────────────────────────┐
                    │       Elasticsearch Cluster              │
                    │  ┌──────────────┐    ┌──────────────┐   │
                    │  │ Dense Vector │    │   Keyword    │   │
                    │  │   (向量检索)  │    │   (关键词)    │   │
                    │  └──────────────┘    └──────────────┘   │
                    │                                          │
                    │  ┌─────────────────────────────────────┐ │
                    │  │        Hybrid Search                │ │
                    │  │    向量相似度 + 关键词匹配           │ │
                    │  └─────────────────────────────────────┘ │
                    └──────────────────────────────────────────┘

//核心代码
                var esDoc = new ProductESDocument
                {
                   
                };

                // 4. 写入ES
                var response = await client.IndexAsync(esDoc, i => i.Index(ProductsIndexName));

                if (response.IsValidResponse)
                {
                    await _db.Updateable<CollectData>()
                        .SetColumns(p => p.EsSyncStatus == 1)
                        .Where(p => p.Id == collectDataId)
                        .ExecuteCommandAsync();
                  
                    return true;
                }
                else
                {
                    await _db.Updateable<CollectData>()
                        .SetColumns(p => p.EsSyncStatus == 2)
                        .Where(p => p.Id == collectDataId)
                        .ExecuteCommandAsync();
          
                    return false;
                }

var searchResponse = await client.SearchAsync<>(s => s
                    .Indices(ProductsIndexName)
                    .Query(q => q
                        .MultiMatch(mm => mm
                            .Fields(new[] { "title^3", "semanticKeywords^2", "description", "brandName" })
                            .Query(request.Query)
                            .Fuzziness(new Fuzziness("AUTO"))
                        )
                    )
                    .Sort(srt => srt.Score(new ScoreSort { Order = SortOrder.Desc }))
                    .From((request.Page - 1) * request.PageSize)
                    .Size(request.PageSize)
                    .SourceExcludes(new[] { "productVector", "imageVector" }) // 排除向量字段,减少返回数据量
                    .Explain() /
                );

                if (!searchResponse.IsValidResponse)
                {
                    _logger.LogError("智能搜索失败: {Error}", searchResponse.ElasticsearchServerError?.Error?.Reason);
                    return new ***
                    {
                        Items = new 
                        Total = 0,
                        Page = request.Page,
                        PageSize = request.PageSize
                    };
                }
5. 容灾与降级策略(C#)
复制代码
public class ResilientSearchService
{
    private readonly HybridSearchService _esService;
    private readonly InMemoryVectorStore<88> _memoryStore;
    private readonly ILogger<99> _logger;

    public async Task<List<SearchResult>> SearchWithFallbackAsync(string query, int topK)
    {
        try
        {
            // 优先 ES
            return await _esService.SearchAsync(query, topK);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "ES 查询失败,降级到内存检索");
            
            try
            {
                // 降级到内存检索
                var queryVector = BgeM3EmbeddingGenerator.GenerateEmbedding(query);
                return await _memoryStore.SearchSimilarAsync(queryVector, topK);
            }
            catch (Exception ex2)
            {
                _logger.LogError(ex2, "内存检索也失败,返回空结果");
                return new List<SearchResult>();
            }
        }
    }
}
6. 分层存储策略
层级 存储介质 数据范围 延迟 用途
L1 C# 本地内存 热点 1万条 1ms 实时推荐
L2 Redis 热点 10万条 5ms 缓存加速
L3 Elasticsearch 全量数据 50ms 完整检索
L4 SQL DB 全量数据 100ms 数据持久化
相关推荐
十铭忘2 小时前
认知循环架构与现有智能体:区别和联系
人工智能·架构
无风听海2 小时前
.NET10之HttpContext.RequestServices 深入解析
.net·asp.net core
杜子不疼.2 小时前
Spring Cloud + AI:微服务架构下的智能路由、故障自愈、日志分析
人工智能·spring cloud·架构
Java后端的Ai之路2 小时前
3 天从入门到可视化监控:Elasticsearch 新手实战指南
大数据·数据库·elasticsearch·搜索引擎·向量数据库
大数据新鸟2 小时前
Elasticsearch(ES)核心知识点
大数据·elasticsearch·搜索引擎
AI探知-阿薇2 小时前
从获取OpenAI API key到Ollama本地部署:Cherry Studio 全栈AI工作站底层架构与生态战略分析
人工智能·架构
ai产品老杨2 小时前
源码级开放与二次开发:基于 Spring Boot 的 AI 视频管理平台架构与 API 深度解析
spring boot·架构·音视频
2501_933329552 小时前
企业级舆情监测系统技术选型指南:Infoseek AI中台架构解析与实践评估
人工智能·分布式·重构·架构
飘忽不定的bug2 小时前
RK3588 linux+rtos(mcu)串口适配
linux·单片机·elasticsearch