Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Nota
Dukungan vektor diperkenalkan di EF Core 10.0, dan hanya didukung dengan SQL Server 2025 ke atas.
Jenis data vektor SQL Server memungkinkan penyimpanan embedding, yang merupakan representasi makna yang dapat dicari secara efisien untuk kesamaan, mendukung beban kerja AI seperti pencarian semantik dan retrieval-augmented generation (RAG).
Menyiapkan properti vektor
Untuk menggunakan vector jenis data, cukup tambahkan properti .NET jenis SqlVector<float> ke jenis entitas Anda, menentukan dimensi sebagai berikut:
public class Blog
{
// ...
[Column(TypeName = "vector(1536)")]
public SqlVector<float> Embedding { get; set; }
}
Setelah properti Anda ditambahkan dan kolom yang sesuai dibuat di database, Anda bisa mulai menyisipkan embedding. Pembuatan embedding dilakukan di luar database, biasanya melalui layanan, dan rincian tentang cara melakukannya tidak termasuk dalam cakupan dokumentasi ini. Namun, pustaka .NET Microsoft.Extensions.AI berisi IEmbeddingGenerator, yang merupakan abstraksi atas penyematan generator yang memiliki implementasi untuk penyedia utama.
Setelah Anda memilih generator embedding dan menyiapkannya, gunakan untuk menghasilkan embedding dan menyisipkannya sebagai berikut:
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator = /* Set up your preferred embedding generator */;
var embedding = await embeddingGenerator.GenerateVectorAsync("Some text to be vectorized");
context.Blogs.Add(new Blog
{
Name = "Some blog",
Embedding = new SqlVector<float>(embedding)
});
await context.SaveChangesAsync();
Setelah penyematan disimpan ke database, Anda siap untuk melakukan pencarian kesamaan vektor di atasnya.
Pencarian yang tepat dengan VECTOR_DISTANCE()
Fungsi ini EF.Functions.VectorDistance() menghitung jarak yang tepat antara dua vektor. Gunakan untuk melakukan pencarian kesamaan untuk kueri pengguna tertentu:
var sqlVector = new SqlVector<float>(await embeddingGenerator.GenerateVectorAsync("Some user query to be vectorized"));
var topSimilarBlogs = await context.Blogs
.OrderBy(b => EF.Functions.VectorDistance("cosine", b.Embedding, sqlVector))
.Take(3)
.ToListAsync();
Fungsi ini menghitung jarak antara vektor kueri dan setiap baris dalam tabel, lalu mengembalikan kecocokan terdekat. Meskipun ini memberikan hasil yang sangat akurat, itu bisa lambat untuk himpunan data besar karena SQL Server harus memindai semua baris dan jarak komputasi untuk masing-masing baris.
Nota
Dukungan bawaan di EF 10 menggantikan ekstensi EFCore.SqlServer.VectorSearch sebelumnya, yang memungkinkan melakukan pencarian vektor sebelum vector jenis data diperkenalkan. Sebagai bagian dari peningkatan ke EF 10, hapus ekstensi dari proyek Anda.
Perkiraan pencarian dengan VECTOR_SEARCH()
Peringatan
VECTOR_SEARCH() dan indeks vektor saat ini adalah fitur eksperimental di SQL Server dan dapat berubah. API di EF Core untuk fitur-fitur ini juga dapat berubah.
Untuk himpunan data besar, menghitung jarak yang tepat untuk setiap baris dapat sangat lambat. SQL Server 2025 memperkenalkan dukungan untuk pencarian perkiraan melalui indeks vektor, yang memberikan performa yang jauh lebih baik dengan mengorbankan pengembalian item yang kira-kira mirip - daripada persis mirip - dengan kueri.
Indeks vektor
Untuk menggunakan VECTOR_SEARCH(), Anda harus membuat indeks vektor pada kolom vektor Anda.
HasVectorIndex() Gunakan metode dalam konfigurasi model Anda:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasVectorIndex(b => b.Embedding, "cosine");
}
Ini akan menghasilkan migrasi SQL berikut:
CREATE VECTOR INDEX [IX_Blogs_Embedding]
ON [Blogs] ([Embedding])
WITH (METRIC = COSINE)
Metrik jarak berikut didukung untuk indeks vektor:
| Ukuran | Deskripsi |
|---|---|
cosine |
Kesamaan kosinus (jarak sudut) |
euclidean |
Jarak euclidean (norma L2) |
dot |
Produk titik (produk dalam negatif) |
Pilih metrik yang paling cocok dengan model penyematan dan kasus penggunaan Anda. Kesamaan kosinus umumnya digunakan untuk penyematan teks, sementara jarak euclidean sering digunakan untuk penyematan gambar.
Mencari dengan VECTOR_SEARCH()
Setelah Anda memiliki indeks vektor, gunakan metode ekstensi VectorSearch() pada DbSet Anda:
var blogs = await context.Blogs
.VectorSearch(b => b.Embedding, "cosine", embedding, topN: 5)
.ToListAsync();
foreach (var (blog, score) in blogs)
{
Console.WriteLine($"Blog {blog.Id} with score {score}");
}
Ini diterjemahkan ke SQL berikut:
SELECT [v].[Id], [v].[Embedding], [v].[Name]
FROM VECTOR_SEARCH([Blogs], 'Embedding', @__embedding, 'metric = cosine', @__topN)
Parameter topN menentukan jumlah maksimum hasil yang akan dikembalikan.
VectorSearch() mengembalikan VectorSearchResult<TEntity>, yang memungkinkan Anda mengakses entitas dan jarak yang dihitung.
var searchResults = await context.Blogs
.VectorSearch(b => b.Embedding, "cosine", embedding, topN: 5)
.Where(r => r.Distance < 0.05)
.Select(r => new { Blog = r.Value, Distance = r.Distance })
.ToListAsync();
Ini memungkinkan Anda untuk memfilter skor kesamaan, menyajikannya kepada pengguna, dll.
Pencarian hibrid
Pencarian hibrid menggabungkan pencarian kesamaan vektor dengan pencarian teks lengkap tradisional untuk memberikan hasil yang lebih relevan. Pencarian vektor unggul dalam menemukan konten semantik yang mirip, sementara pencarian teks lengkap lebih baik pada pencocokan kata kunci yang tepat. Dengan menggabungkan kedua pendekatan dan menggunakan Reciprocal Rank Fusion (RRF) untuk menggabungkan hasilnya, Anda dapat membangun pengalaman pencarian yang lebih cerdas.
Contoh berikut menunjukkan cara menerapkan pencarian hibrid menggunakan EF Core, menggabungkan FreeTextTable() , dan VectorSearch() dalam satu kueri:
var k = 20;
string textualQuery = ...;
SqlVector<float> queryEmbedding = ...;
var results = await context.Articles
// Perform full-text search
.FreeTextTable<Article, int>(textualQuery, topN: k)
// Perform vector (semantic) search, joining the results of both searches together
.LeftJoin(
context.Articles.VectorSearch(b => b.Embedding, queryEmbedding, "cosine", topN: k),
fts => fts.Key,
vs => vs.Value.Id,
(fts, vs) => new
{
Article = vs.Value,
FullTextRank = fts.Rank,
VectorDistance = (double?)vs.Distance
})
// Apply Reciprocal Rank Fusion (RRF) to combine the results
.Select(x => new
{
x.Article,
RrfScore = (1.0 / (k + x.FullTextRank)) + (1.0 / (k + x.VectorDistance) ?? 0.0)
})
.OrderByDescending(x => x.RrfScore)
.Take(10)
.Select(x => x.Article)
.ToListAsync();
Kueri ini:
- Melakukan pencarian teks lengkap pada
Article - Melakukan pencarian vektor pada
Articledan menggabungkan hasilnya dengan hasil pencarian teks lengkap melalui LEFT JOIN. - Menghitung skor RRF dengan menggabungkan teks lengkap dan peringkat semantik
- Mengurutkan berdasarkan skor RRF, mengambil hasil sejumlah yang diinginkan dan mengeluarkan entitas asli
Article.
Nota
Daripada menggunakan LEFT JOIN, FULL OUTER JOIN akan lebih cocok untuk skenario ini; ini akan memungkinkan hasil peringkat tinggi dari kedua sisi pencarian untuk disertakan dalam hasil akhir, meskipun hasil tersebut tidak muncul sama sekali di sisi yang lain. Dengan pendekatan LEFT JOIN di atas, jika hasil memiliki skor kesamaan vektor yang sangat tinggi, itu tidak pernah disertakan dalam hasil akhir jika hasil itu tidak juga memiliki skor teks lengkap yang tinggi. Namun, EF saat ini tidak mendukung FULL OUTER JOIN; upvote #37633 jika ini adalah sesuatu yang ingin Anda lihat didukung.
Kueri menghasilkan SQL berikut:
SELECT TOP(@p3) [a0].[Id], [a0].[Content], [a0].[Embedding], [a0].[Title]
FROM FREETEXTTABLE([Articles], *, @p, @p1) AS [f]
LEFT JOIN VECTOR_SEARCH(
TABLE = [Articles] AS [a0],
COLUMN = [Embedding],
SIMILAR_TO = @p2,
METRIC = 'cosine',
TOP_N = @p3
) AS [v] ON [f].[KEY] = [a0].[Id]
ORDER BY 1.0E0 / CAST(10 + [f].[RANK] AS float) + ISNULL(1.0E0 / (10.0E0 + [v].[Distance]), 0.0E0) DESC