Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
SQL Server offre funzionalità di ricerca full-text che consentono ricerche di testo sofisticate oltre a modelli semplici LIKE . La ricerca full-text supporta il confronto linguistico, le forme flesse, la ricerca di prossimità e la classificazione ponderata.
Il provider SQL Server di EF Core supporta predicati di ricerca full-text (per il filtro) e funzioni con valori di tabella (per filtrare con classificazione).
Configurazione della ricerca testuale completa
Prima di usare la ricerca full-text, è necessario creare un catalogo full-text nel database e un indice full-text nelle colonne da cercare.
Annotazioni
Il catalogo full-text e la gestione degli indici nelle migrazioni sono stati introdotti in EF Core 11.
È possibile configurare cataloghi e indici full-text direttamente nel modello di Entity Framework. Quando si aggiunge una migrazione, Entity Framework genererà il codice SQL appropriato per creare (o modificare) il catalogo e l'indice.
Prima di tutto, definire un catalogo full-text nel modello, quindi configurare un indice full-text nel tipo di entità:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasFullTextCatalog("ftCatalog");
modelBuilder.Entity<Article>()
.HasFullTextIndex(a => a.Contents)
.HasKeyIndex("PK_Articles")
.OnCatalog("ftCatalog");
}
Il HasKeyIndex() metodo specifica l'indice univoco, non annullabile, a colonna singola utilizzato come chiave full-text per la tabella (in genere l'indice della chiave primaria).
OnCatalog() assegna l'indice full-text a un catalogo specifico.
È anche possibile configurare più colonne e opzioni aggiuntive, ad esempio lingue per colonna e rilevamento modifiche:
modelBuilder.Entity<Article>()
.HasFullTextIndex(a => new { a.Title, a.Contents })
.HasKeyIndex("PK_Articles")
.OnCatalog("ftCatalog")
.WithChangeTracking(FullTextChangeTracking.Manual)
.HasLanguage("Title", "English")
.HasLanguage("Contents", "French");
Il catalogo full-text può anche essere configurato come catalogo predefinito con sensibilità agli accenti.
modelBuilder.HasFullTextCatalog("ftCatalog")
.IsDefault()
.IsAccentSensitive(false);
Per altre informazioni, vedere la documentazione di ricerca full-text di SQL Server.
Predicati di testo completo
EF Core supporta i FREETEXT() predicati e CONTAINS() , usati nelle Where() clausole per filtrare i risultati.
FREETEXT()
FREETEXT() esegue una corrispondenza meno rigorosa, cercando parole in base al loro significato, incluse le forme flessive (ad esempio i verbi tensi e i plurali sostantivali):
var articles = await context.Articles
.Where(a => EF.Functions.FreeText(a.Contents, "veggies"))
.ToListAsync();
Questo si traduce in:
SELECT [a].[Id], [a].[Title], [a].[Contents]
FROM [Articles] AS [a]
WHERE FREETEXT([a].[Contents], N'veggies')
Facoltativamente, è possibile specificare un termine linguistico:
var articles = await context.Articles
.Where(a => EF.Functions.FreeText(a.Contents, "veggies", "English"))
.ToListAsync();
CONTAINS()
CONTAINS() esegue una corrispondenza più precisa e supporta criteri di ricerca più sofisticati, tra cui termini di prefisso, ricerca di prossimità e termini ponderati:
// 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();
Questo si traduce in:
SELECT [a].[Id], [a].[Title], [a].[Contents]
FROM [Articles] AS [a]
WHERE CONTAINS([a].[Contents], N'veggies')
Per altre informazioni sulla sintassi delle CONTAINS() query, vedere la documentazione di SQL Server CONTAINS.
Funzioni con valori di tabella full-text
Annotazioni
Le funzioni con valori di tabella full-text vengono introdotte in EF Core 11.
Anche se i predicati precedenti sono utili per filtrare, non forniscono informazioni di classificazione. Le funzioni FREETEXTTABLE() con valori di tabella di SQL Server e CONTAINSTABLE() restituiscono sia righe corrispondenti che un punteggio di classificazione che indica il livello di corrispondenza di ogni riga corrispondente alla query di ricerca.
FreeTextTable()
FreeTextTable() è la versione della funzione con valori di tabella di FreeText(). Restituisce FullTextSearchResult<TEntity>, che include sia l'entità che il valore di classificazione:
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}");
}
Si noti che è necessario specificare i parametri di tipo generico; Article corrisponde al tipo di entità in cui viene eseguita la ricerca, dove int è la chiave di ricerca full-text specificata durante la creazione dell'indice e restituita da FREETEXTTABLE().
La ricerca automatica sopra inclusa esegue la ricerca a testo intero in tutte le colonne registrate e restituisce le prime 10 corrispondenze. È anche possibile specificare una colonna specifica per la ricerca:
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();
... o più colonne:
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() è la versione della funzione che restituisce valori di tabella di Contains(), supportando la stessa sintassi sofisticata di ricerca e fornendo anche informazioni di ranking:
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();
Limitazione dei risultati
Entrambe le funzioni con valori di tabella supportano un topN parametro per limitare il numero di risultati:
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();
Specifica di una lingua
Entrambe le funzioni con valori di tabella supportano la specifica di un termine linguistico per la corrispondenza linguistica:
var results = await context.Articles
.FreeTextTable(a => a.Contents, "veggies", languageTerm: "English")
.Select(r => new { Article = r.Value, Rank = r.Rank })
.ToListAsync();
Quando usare predicati e funzioni con valori di tabella
| Feature | Predicati (FreeText(), Contains()) |
Funzioni con valori di tabella (FreeTextTable(), ContainsTable()) |
|---|---|---|
| Fornisce la classificazione | ❌ No | ✅ Sì |
| Prestazioni per set di risultati di grandi dimensioni | Migliore per filtrare | Migliore per la classificazione e l'ordinamento |
| Combinare con altre entità | via join | Risultato entità integrata |
Usare nella clausola Where() |
✅ Sì | ❌ No (usare come origine) |
Usare i predicati quando è sufficiente filtrare i risultati in base ai criteri di ricerca full-text. Usare funzioni con valori di tabella quando sono necessarie informazioni di classificazione per ordinare i risultati in base alla pertinenza o visualizzare i punteggi di pertinenza per gli utenti.