Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
SQL Server proporciona funcionalidades de búsqueda de texto completo que permiten una búsqueda de texto sofisticada más allá de patrones simples LIKE . La búsqueda de texto completo admite la coincidencia lingüística, los formularios inflectionales, la búsqueda por proximidad y la clasificación ponderada.
El proveedor de SQL Server de EF Core admite predicados de búsqueda de texto completo (para filtrar) y funciones con valores de tabla (para filtrar con clasificación).
Configuración de la búsqueda de texto completo
Antes de usar la búsqueda de texto completo, debe crear un catálogo de texto completo en la base de datos y un índice de texto completo en las columnas que desea buscar.
Nota:
El catálogo de texto completo y la administración de índices en las migraciones se introdujo en EF Core 11.
Puede configurar catálogos e índices de texto completo directamente en el modelo de EF. Al agregar una migración, EF generará el SQL adecuado para crear (o modificar) el catálogo y el índice para usted.
En primer lugar, defina un catálogo de texto completo en el modelo y, a continuación, configure un índice de texto completo en el tipo de entidad:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasFullTextCatalog("ftCatalog");
modelBuilder.Entity<Article>()
.HasFullTextIndex(a => a.Contents)
.HasKeyIndex("PK_Articles")
.OnCatalog("ftCatalog");
}
El método HasKeyIndex() especifica el índice único, no anulable, de una sola columna que se utiliza como clave para texto completo en la tabla (normalmente el índice de clave primaria).
OnCatalog() asigna el índice de texto completo a un catálogo específico.
También puede configurar varias columnas y opciones adicionales, como los idiomas por columna y el seguimiento de cambios:
modelBuilder.Entity<Article>()
.HasFullTextIndex(a => new { a.Title, a.Contents })
.HasKeyIndex("PK_Articles")
.OnCatalog("ftCatalog")
.WithChangeTracking(FullTextChangeTracking.Manual)
.HasLanguage("Title", "English")
.HasLanguage("Contents", "French");
El catálogo de texto completo también se puede configurar como el catálogo predeterminado y con sensibilidad de énfasis:
modelBuilder.HasFullTextCatalog("ftCatalog")
.IsDefault()
.IsAccentSensitive(false);
Para obtener más información, consulte la documentación de búsqueda de texto completo de SQL Server.
Predicados de texto completo
EF Core admite los FREETEXT() y CONTAINS() predicados, que se usan en las cláusulas Where() para filtrar los resultados.
FREETEXT()
FREETEXT() realiza una coincidencia menos estricta, buscando palabras en función de su significado, incluidas las formas flexivas (como tiempos verbales y plurales de sustantivos):
var articles = await context.Articles
.Where(a => EF.Functions.FreeText(a.Contents, "veggies"))
.ToListAsync();
Esto se traduce en:
SELECT [a].[Id], [a].[Title], [a].[Contents]
FROM [Articles] AS [a]
WHERE FREETEXT([a].[Contents], N'veggies')
Opcionalmente, puede especificar un término de idioma:
var articles = await context.Articles
.Where(a => EF.Functions.FreeText(a.Contents, "veggies", "English"))
.ToListAsync();
CONTAINS()
CONTAINS() realiza coincidencias más precisas y admite criterios de búsqueda más sofisticados, incluidos los términos de prefijo, la búsqueda por proximidad y los términos ponderados:
// 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();
Esto se traduce en:
SELECT [a].[Id], [a].[Title], [a].[Contents]
FROM [Articles] AS [a]
WHERE CONTAINS([a].[Contents], N'veggies')
Para obtener más información sobre la CONTAINS() sintaxis de consulta, consulte la documentación de SQL Server CONTAINS.
Funciones con valores de tabla de texto completo
Nota:
Las funciones con valores de tabla de texto completo se presentan en EF Core 11.
Aunque los predicados anteriores son útiles para el filtrado, no proporcionan información de clasificación. Las funciones FREETEXTTABLE() con valores de tabla de SQL Server y CONTAINSTABLE() devuelven filas coincidentes y una puntuación de clasificación que indica cómo coincide cada fila con la consulta de búsqueda.
FreeTextTable()
FreeTextTable() es la versión de función con valores de tabla de FreeText(). Devuelve FullTextSearchResult<TEntity>, que incluye tanto la entidad como el valor de clasificación:
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}");
}
Tenga en cuenta que debe proporcionar los parámetros de tipo genérico; Article corresponde al tipo de entidad que se busca, donde int es la clave de búsqueda de texto completo especificada al crear el índice y que devuelve FREETEXTTABLE().
Lo anterior busca automáticamente en todas las columnas registradas para la búsqueda de texto completo y devuelve las 10 primeras coincidencias. También puede proporcionar una columna específica para buscar:
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 varias columnas:
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() es la versión de función con valores de tabla de Contains(), que admite la misma sintaxis de búsqueda sofisticada, al tiempo que proporciona información de clasificación:
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();
Limitar los resultados
Ambas funciones con valores de tabla admiten un topN parámetro para limitar el número de resultados:
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();
Especificación de un idioma
Ambas funciones con valores de tabla admiten la especificación de un término de lenguaje para la coincidencia lingüística:
var results = await context.Articles
.FreeTextTable(a => a.Contents, "veggies", languageTerm: "English")
.Select(r => new { Article = r.Value, Rank = r.Rank })
.ToListAsync();
Cuándo usar predicados frente a funciones con valores de tabla
| Feature | Predicados (FreeText(), Contains()) |
Funciones con valores de tabla (FreeTextTable(), ContainsTable()) |
|---|---|---|
| Proporciona clasificación | ❌ No | ✅ Sí |
| Rendimiento de conjuntos de resultados grandes | Mejor para filtrar | Mejor para clasificar y ordenar |
| Combinación con otras entidades | Mediante combinaciones | Resultado de la entidad integrada |
Usar en la cláusula Where() |
✅ Sí | ❌ No (se usa como origen) |
Use predicados cuando simplemente necesite filtrar los resultados en función de los criterios de búsqueda de texto completo. Use funciones con valores de tabla cuando necesite información de clasificación para ordenar los resultados por relevancia o mostrar puntuaciones de relevancia a los usuarios.