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.
SQL Server menyediakan kemampuan pencarian teks lengkap yang memungkinkan pencarian teks canggih di luar pola sederhana LIKE . Pencarian teks lengkap mendukung pencocokan linguistik, bentuk infleksi, pencarian kedekatan, dan peringkat tertimbang.
Penyedia SQL Server EF Core mendukung predikat pencarian teks lengkap (untuk pemfilteran) dan fungsi bernilai tabel (untuk pemfilteran dengan peringkat).
Menyiapkan pencarian teks lengkap
Sebelum menggunakan pencarian teks lengkap, Anda harus membuat katalog teks lengkap di database Anda, dan indeks teks lengkap pada kolom yang ingin Anda cari.
Nota
Katalog teks lengkap dan manajemen indeks dalam migrasi diperkenalkan di EF Core 11.
Anda dapat mengonfigurasi katalog teks lengkap dan indeks langsung dalam model EF Anda. Saat Anda menambahkan migrasi, EF akan menghasilkan SQL yang sesuai untuk membuat (atau mengubah) katalog dan indeks untuk Anda.
Pertama, tentukan katalog teks lengkap pada model, lalu konfigurasikan indeks teks lengkap pada jenis entitas Anda:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasFullTextCatalog("ftCatalog");
modelBuilder.Entity<Article>()
.HasFullTextIndex(a => a.Contents)
.HasKeyIndex("PK_Articles")
.OnCatalog("ftCatalog");
}
Metode HasKeyIndex() menentukan indeks kolom tunggal yang unik, tidak dapat bernilai null yang digunakan sebagai kunci teks lengkap untuk tabel (biasanya indeks kunci utama).
OnCatalog() menetapkan indeks teks lengkap ke katalog tertentu.
Anda juga dapat mengonfigurasi beberapa kolom dan opsi tambahan seperti bahasa per kolom dan pelacakan perubahan:
modelBuilder.Entity<Article>()
.HasFullTextIndex(a => new { a.Title, a.Contents })
.HasKeyIndex("PK_Articles")
.OnCatalog("ftCatalog")
.WithChangeTracking(FullTextChangeTracking.Manual)
.HasLanguage("Title", "English")
.HasLanguage("Contents", "French");
Katalog teks lengkap juga dapat dikonfigurasi sebagai katalog default, dan dengan sensitivitas aksen:
modelBuilder.HasFullTextCatalog("ftCatalog")
.IsDefault()
.IsAccentSensitive(false);
Untuk informasi selengkapnya, lihat dokumentasi pencarian teks lengkap SQL Server.
Predikat teks lengkap
EF Core mendukung FREETEXT() dan CONTAINS() yang digunakan dalam klausa Where() untuk memfilter hasil.
FREETEXT()
FREETEXT() melakukan pencocokan yang kurang ketat, mencari kata-kata berdasarkan maknanya, termasuk bentuk infleksi (seperti bentuk kata kerja dan jamak kata benda):
var articles = await context.Articles
.Where(a => EF.Functions.FreeText(a.Contents, "veggies"))
.ToListAsync();
Ini diterjemahkan ke:
SELECT [a].[Id], [a].[Title], [a].[Contents]
FROM [Articles] AS [a]
WHERE FREETEXT([a].[Contents], N'veggies')
Anda dapat secara opsional menentukan istilah bahasa:
var articles = await context.Articles
.Where(a => EF.Functions.FreeText(a.Contents, "veggies", "English"))
.ToListAsync();
CONTAINS()
CONTAINS() melakukan pencocokan yang lebih tepat dan mendukung kriteria pencarian yang lebih canggih, termasuk istilah awalan, pencarian kedekatan, dan istilah tertimbang:
// Simple search
var articles = await context.Articles
.Where(a => EF.Functions.Contains(a.Contents, "veggies"))
.ToListAsync();
// Prefix search (words starting with "vegg")
var articles = await context.Articles
.Where(a => EF.Functions.Contains(a.Contents, "\"vegg*\""))
.ToListAsync();
// Phrase search
var articles = await context.Articles
.Where(a => EF.Functions.Contains(a.Contents, "\"fresh vegetables\""))
.ToListAsync();
Ini diterjemahkan ke:
SELECT [a].[Id], [a].[Title], [a].[Contents]
FROM [Articles] AS [a]
WHERE CONTAINS([a].[Contents], N'veggies')
Untuk informasi selengkapnya tentang CONTAINS() sintaks kueri, lihat dokumentasi SQL Server CONTAINS.
Fungsi bernilai tabel teks lengkap
Nota
Fungsi bernilai tabel teks lengkap sedang diperkenalkan di EF Core 11.
Meskipun predikat di atas berguna untuk pemfilteran, predikat tersebut tidak memberikan informasi peringkat. Fungsi bernilai tabel SQL Server FREETEXTTABLE() dan CONTAINSTABLE() mengembalikan baris yang cocok serta skor peringkat yang menunjukkan tingkat kecocokan setiap baris dengan kueri pencarian.
FreeTextTable()
FreeTextTable() adalah versi fungsi bernilai tabel dari FreeText(). Ini mengembalikan FullTextSearchResult<TEntity>, yang mencakup entitas dan nilai peringkat:
var results = await context.Articles
.Join(
context.Articles.FreeTextTable<Article, int>("veggies", topN: 10),
a => a.Id,
ftt => ftt.Key,
(a, ftt) => new { Article = a, ftt.Rank })
.OrderByDescending(r => r.Rank)
.ToListAsync();
foreach (var result in results)
{
Console.WriteLine($"Article {result.Article.Id} with rank {result.Rank}");
}
Perhatikan bahwa Anda harus memberikan parameter jenis generik; Article sesuai dengan jenis entitas yang sedang dicari, di mana int adalah kunci pencarian teks lengkap yang ditentukan saat membuat indeks, dan yang dikembalikan oleh FREETEXTTABLE().
Proses di atas secara otomatis mencari seluruh kolom yang terdaftar untuk pencarian teks penuh dan mengembalikan 10 kecocokan teratas. Anda juga dapat menyediakan kolom tertentu untuk dicari:
var results = await context.Articles
.Join(
context.Articles.FreeTextTable<Article, int>(a => a.Contents, "veggies"),
a => a.Id,
ftt => ftt.Key,
(a, ftt) => new { Article = a, ftt.Rank })
.OrderByDescending(r => r.Rank)
.ToListAsync();
... atau beberapa kolom:
var results = await context.Articles
.FreeTextTable(a => new { a.Title, a.Contents }, "veggies")
.Select(r => new { Article = r.Value, Rank = r.Rank })
.OrderByDescending(r => r.Rank)
.ToListAsync();
ContainsTable()
ContainsTable() adalah versi fungsi bernilai tabel dari Contains(), mendukung sintaks pencarian canggih yang sama sekaligus memberikan informasi peringkat:
var results = await context.Articles
.Join(
context.Articles.ContainsTable<Article, int>( "veggies OR fruits"),
a => a.Id,
ftt => ftt.Key,
(a, ftt) => new { Article = a, ftt.Rank })
.OrderByDescending(r => r.Rank)
.ToListAsync();
Membatasi hasil
Kedua fungsi yang memiliki nilai tabel mendukung parameter topN untuk membatasi jumlah hasil.
var results = await context.Articles
.FreeTextTable(a => a.Contents, "veggies", topN: 10)
.Select(r => new { Article = r.Value, Rank = r.Rank })
.OrderByDescending(r => r.Rank)
.ToListAsync();
Menentukan bahasa
Kedua fungsi bernilai tabel mendukung menentukan istilah bahasa untuk pencocokan linguistik:
var results = await context.Articles
.FreeTextTable(a => a.Contents, "veggies", languageTerm: "English")
.Select(r => new { Article = r.Value, Rank = r.Rank })
.ToListAsync();
Kapan menggunakan predikat vs. fungsi dengan nilai tabel
| Feature | Predikat (FreeText(), Contains()) |
Fungsi bernilai tabel (FreeTextTable(), ContainsTable()) |
|---|---|---|
| Menyediakan peringkat | ❌ Tidak | ✅ Ya |
| Kinerja untuk set hasil berukuran besar | Lebih baik untuk pemfilteran | Lebih baik untuk peringkat dan pengurutan |
| Gabungkan dengan entitas lain | Melalui gabungan | Hasil entitas bawaan |
Dalam klausa Where(), gunakan |
✅ Ya | ❌ Tidak (gunakan sebagai sumber) |
Gunakan predikat saat Anda hanya perlu memfilter hasil berdasarkan kriteria pencarian teks lengkap. Gunakan fungsi bernilai tabel saat Anda memerlukan informasi peringkat untuk mengurutkan hasil berdasarkan relevansi atau menampilkan skor relevansi kepada pengguna.