學院新聞

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

如果您正在構建處理大量數據、文件、產品目錄、客戶紀錄或掃描檔案的.NET應用程式,搜尋總是一個挑戰。 關鍵字搜尋缺乏上下文。 全文搜尋有其限制。 但向量搜尋則完全改變了這個等式。

我們最近發現了一個由Milan Jovanović撰寫的優秀指南,他是.NET社區中最受尊敬的聲音之一,亦是Microsoft MVP,該指南詳細介紹了如何使用PgVector在.NET中實施向量搜尋,這是一個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,您可以使用相同的docker-compose運行並用常規連接字串指向它。

本節是基於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擁有您所需的一切。