Tworzenie wyszukiwania wektorowego w .NET za pomocą PgVector, przewodnik dla programistów
Jeśli tworzysz aplikacje .NET, które obsługują duże ilości danych, dokumentów, katalogów produktów, rekordów klientów lub zeskanowanych plików, wyszukiwanie zawsze stanowi wyzwanie. Wyszukiwanie słów kluczowych nie uwzględnia kontekstu. Wyszukiwanie pełnotekstowe ma swoje ograniczenia. Jednak wyszukiwanie wektorowe całkowicie zmienia sytuację.
Niedawno natknęliśmy się na doskonały przewodnik autorstwa Milana Jovanovicia, jednego z najbardziej szanowanych głosów w społeczności .NET i Microsoft MVP, który szczegółowo opisuje, jak zaimplementować wyszukiwanie wektorowe w .NET przy użyciu PgVector, rozszerzenia PostgreSQL, które wprowadza możliwości wyszukiwania semantycznego bezpośrednio do bazy danych, którą już posiadasz.
Co to jest wyszukiwanie wektorowe i jak działa?
Tradycyjne wyszukiwanie dopasowuje dokładne słowa lub frazy. Jeżeli użytkownik szuka "przeterminowanej faktury", wyszukiwanie według słów kluczowych znajdzie jedynie dokumenty zawierające te dokładne słowa. Nie wyświetli dokumentu, który mówi "płatność oczekująca" lub "saldo należne", nawet gdy oznaczają to samo.
Wyszukiwanie wektorowe działa inaczej. Zamiast dopasowywać słowa, dopasowuje znaczenie.
Oto jak działa pipeline w praktyce:
Po pierwsze, tekst jest konwertowany na reprezentację numeryczną zwaną osadzeniem, czyli wielowymiarową tablicę liczb zmiennoprzecinkowych, która uchwyca znaczenie semantyczne treści. Na przykład, zdania "przeterminowana faktura" i "płatność oczekuje" wygenerowałyby osadzenia, które są matematycznie bliskie sobie w przestrzeni wektorowej, mimo że nie mają wspólnych słów.
Te osadzenia są generowane przez model uczenia maszynowego, zazwyczaj za pośrednictwem API, takiego jak modele osadzania tekstu OpenAI, i przechowywane razem z danymi w bazie danych.

Gdy użytkownik uruchamia zapytanie wyszukiwania, to zapytanie jest również konwertowane na osadzenie przy użyciu tego samego modelu. Baza danych następnie oblicza odległość między osadzeniem zapytania a każdym przechowywanym osadzeniem, zwracając wyniki, które są najbliższe w przestrzeni wektorowej, co oznacza najbardziej semantycznie podobne, a nie tylko dopasowane słowami kluczowymi.
PgVector umożliwia to bezpośrednio w PostgreSQL, wspierając efektywne wyszukiwanie podobieństw obok danych relacyjnych, bez potrzeby dedykowanej bazy danych wektorowej.
Inicjalizacja bazy danych
Przed przechowywaniem wektorów, należy włączyć rozszerzenie PgVector i skonfigurować tabelę.
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();Jesli nie uzywasz Aspire, mozesz uruchomic ten sam obraz pgvector/pgvector:pg17 za pomoca docker-compose i wskazac go za pomoca standardowego ciagu polaczenia.
Ta sekcja opiera się na oryginalnym artykułe Milana Jovanovicia. Pełne przykłady kodu i szczegóły implementacji są dostępne tutaj.
Dłączego to jest ważne dla klientów Iron Software
Wielu naszych klientów używa IronPDF, IronOCR i IronBarcode do przetwarzania dużych ilości dokumentów; faktur, raportów, zeskanowanych dokumentów, etykiet wysyłkowych.
Praktyczny przepływ pracy łączący biblioteki Iron Software z PgVectorem może wyglądać tak:
Extract– Uzyj IronOCR, aby wyodrebnic tekst ze skanowanych PDFow lub obrazowEmbed– Wyslij wyodrebniony tekst do modelu osadzania, aby wygenerowac reprezentacje wektoroweStore– Zapisz osadzenia wraz z metadanymi dokumentu w PostgreSQL, korzystajac z PgvectorSearch– Wyszukuj wedlug znaczenia, zwracajac dokumenty najbardziej semantycznie relevantne, zamiast dokladnych dopasowan slów kluczowych
Wynikiem jest inteligentniejszy system wyszukiwania dokumentów zbudowany całkowicie w ramach istniejącego stosu .NET i PostgreSQL, bez dodatkowej infrastruktury.
Co obejmuje przewodnik Milana
Artykuł Milana opisuje pełną implementację w C#: ustawienie rozszerzenia PgVector w PostgreSQL, konfigurowanie Entity Framework Core z Npgsql, generowanie osadzeń, tworzenie indeksów wektorowych dla wydajności i wykonywanie zapytań o podobieństwo. Jest praktyczny, zoptymalizowany do produkcji i od razu użyteczny dla każdego programisty .NET.
Zespół programistów Iron Software regularnie dzieli się zasobami .NET, poradnikami i wnioskami inżynieryjnymi z naszą społecznością.
Budujesz przepływy pracy z dokumentami w .NET? Iron Suite ma wszystko, czego potrzebujesz.
