学院新闻

在.NET中使用PgVector构建向量搜索,开发者指南

如果您正在构建处理大量数据、文档、产品目录、客户记录或扫描文件的.NET应用程序,搜索始终是一个挑战。 关键词搜索会遗漏上下文。 全文搜索有其局限性。 但向量搜索则完全改变了这种传统。

我们最近发现了一篇很好的指南,作者是Milan Jovanović,他是.NET社区中最受尊重的声音之一,也是Microsoft MVP。他详细讲解了如何在.NET中使用PgVector实现向量搜索,这是一个将语义搜索功能直接引入现有数据库的PostgreSQL扩展。

什么是向量搜索以及它如何运作?

传统搜索是匹配准确的单词或短语。 如果用户搜索"发票逾期",关键词搜索只会找到包含这些确切单词的文档。 它不会显示写有"付款待处理"或"余额到期"的文档,即使它们意思一样。

向量搜索的工作方式截然不同。 不是匹配单词,而是匹配意义。

以下是实际中的流程如何工作:

首先,将文本转换为一个称为嵌入的数值表示形式,这是一个捕捉内容语义含义的浮点数高维数组。 例如,句子"欠款发票"和"付款待处理"将产生在向量空间中数学上彼此接近的嵌入,即使它们没有共同的单词。

这些嵌入由机器学习模型生成,通常通过像OpenAI的文本嵌入模型这样的API,并与您的数据一起存储在数据库中。

图像 1

当用户运行搜索查询时,该查询也会使用相同的模型转换为嵌入。 然后数据库计算查询嵌入与每个存储的嵌入之间的距离,返回在向量空间中最接近的结果,意味着最具语义相似性,而不是仅仅关键词匹配。

PgVector直接在PostgreSQL中启用此功能,在不需要专用向量数据库的情况下支持高效的相似性搜索,就在您的关系数据旁边。

初始化数据库

在存储向量之前,启用PgVector扩展并设置表。


var builder = DistributedApplication.CreateBuilder(args);

var ollama = builder.AddOllama("ollama")
    .WithLifetime(ContainerLifetime.Persistent)
    .WithDataVolume()
    .WithGPUSupport();

var embeddingModel = ollama.AddModel("qwen3-embedding:0.6b");

var postgres = builder.AddPostgres("postgres", port: 6432)
    .WithLifetime(ContainerLifetime.Persistent)
    .WithDataVolume()
    .WithImage("pgvector/pgvector", "pg17")
    .AddDatabase("articles");

builder.AddProject<Projects.PgVector_Articles>("pgvector-articles")
    .WithReference(embeddingModel)
    .WithReference(postgres)
    .WaitFor(embeddingModel)
    .WaitFor(postgres);

builder.Build().Run();

var builder = DistributedApplication.CreateBuilder(args);

var ollama = builder.AddOllama("ollama")
    .WithLifetime(ContainerLifetime.Persistent)
    .WithDataVolume()
    .WithGPUSupport();

var embeddingModel = ollama.AddModel("qwen3-embedding:0.6b");

var postgres = builder.AddPostgres("postgres", port: 6432)
    .WithLifetime(ContainerLifetime.Persistent)
    .WithDataVolume()
    .WithImage("pgvector/pgvector", "pg17")
    .AddDatabase("articles");

builder.AddProject<Projects.PgVector_Articles>("pgvector-articles")
    .WithReference(embeddingModel)
    .WithReference(postgres)
    .WaitFor(embeddingModel)
    .WaitFor(postgres);

builder.Build().Run();

如果您不使用Aspire,您可以通过pgvector/pgvector:pg17图像,并使用常规连接字符串指向它。

本节基于Milan Jovanović的原创文章。 完整的代码示例和实现细节可在此处获取。

为什么这对Iron Software的客户很重要

我们的许多客户使用IronPDFIronOCRIronBarcode处理大量文档; 发票、报告、扫描记录、运输标签。

结合Iron Software库与PgVector的实践工作流程可能如下:

  1. Extract – 使用IronOCR从扫描的PDF或图像中提取文本
  2. Embed – 将提取的文本发送到嵌入模型以生成向量表示
  3. Store – 使用Pgvector将嵌入与文档元数据一起保存在PostgreSQL中
  4. Search – 根据含义查询,返回语义上最相关的文档而非精确的关键词匹配

结果是一个在您现有.NET和PostgreSQL技术栈中完全构建的更智能的文档搜索系统,无需额外的基础设施。

Milan的指南涵盖哪些内容

Milan的文章详细讲解了完整的C#实现:在PostgreSQL中设置PgVector扩展,配置Entity Framework Core与Npgsql,生成嵌入,为性能创建向量索引,以及运行相似性查询。 它是实用导向的,面向生产的,立即适用于任何.NET开发者。

Iron Software开发团队定期与我们的社区分享.NET资源、教程和工程见解。

在.NET中构建文档工作流程? Iron Suite拥有您所需的一切。