Partager via


Recherche en texte intégral

Azure Cosmos DB offre désormais la prise en charge de la recherche en texte intégral. Cela permet des recherches de texte efficaces et efficientes à l’aide de techniques avancées telles que la lemmatisation, ainsi que l’évaluation de la pertinence des documents par rapport à une requête de recherche donnée. Il peut être utilisé en combinaison avec la recherche vectorielle (recherche hybride) pour améliorer la précision des réponses dans certains scénarios d’IA. EF Core permet de modéliser la base de données avec des propriétés activées pour la recherche en texte intégral et d’utiliser des fonctions de recherche en texte intégral dans des requêtes ciblant Azure Cosmos DB.

Configuration du modèle

Une propriété peut être configurée à l’intérieur OnModelCreating pour utiliser la recherche en texte intégral en l’activant pour la propriété et en définissant un index de recherche en texte intégral :

public class Blog
{
    ...

    public string Contents { get; set; }
}

public class BloggingContext
{
    ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>(b =>
        {
            b.Property(x => x.Contents).EnableFullTextSearch();
            b.HasIndex(x => x.Contents).IsFullTextIndex();
        });
    }
}

Remarque

La configuration de l’index n’est pas obligatoire, mais elle est recommandée car elle améliore considérablement les performances des requêtes de recherche en texte intégral.

Les opérations de recherche en texte intégral sont spécifiques à la langue, à l’aide de l’anglais américain (en-US) par défaut. Vous pouvez personnaliser le langage pour chaque propriété individuelle dans le cadre de l’appel EnableFullTextSearch:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>(b =>
        {
            b.Property(x => x.Contents).EnableFullTextSearch();
            b.HasIndex(x => x.Contents).IsFullTextIndex();
            b.Property(x => x.ContentsGerman).EnableFullTextSearch("de-DE");
            b.HasIndex(x => x.ContentsGerman).IsFullTextIndex();
        });
    }

Vous pouvez également définir une langue par défaut pour le conteneur, sauf si elle est remplacée dans la EnableFullTextSearch méthode, toutes les propriétés de texte intégral à l’intérieur du conteneur utilisent cette langue.

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>(b =>
        {
            b.HasDefaultFullTextLanguage("de-DE");
            b.Property(x => x.ContentsEnglish).EnableFullTextSearch("en-US");
            b.HasIndex(x => x.ContentsEnglish).IsFullTextIndex();
            b.Property(x => x.ContentsGerman).EnableFullTextSearch();
            b.HasIndex(x => x.ContentsGerman).IsFullTextIndex();
            b.Property(x => x.TagsGerman).EnableFullTextSearch();
            b.HasIndex(x => x.TagsGerman).IsFullTextIndex();
        });
    }

Interrogation

Dans le cadre de la fonctionnalité de recherche en texte intégral, Azure Cosmos DB a introduit plusieurs fonctions intégrées qui permettent d’interroger efficacement le contenu à l’intérieur des propriétés activées pour la recherche en texte intégral. Ces fonctions sont les suivantes : FullTextContains, FullTextContainsAll, FullTextContainsAnyqui recherchent des mots clés ou des mots clés spécifiques et FullTextScore, qui retourne le score BM25 en fonction des mots clés fournis.

Remarque

FullTextScore ne peut être utilisé qu’à l’intérieur OrderBy pour classer les documents en fonction du score.

EF Core expose ces fonctions comme partie de EF.Functions afin qu'elles puissent être utilisées dans les requêtes :

var cosmosBlogs = await context.Blogs.Where(x => EF.Functions.FullTextContainsAll(x.Contents, "database", "cosmos")).ToListAsync();

var keywords = new string[] { "AI", "agent", "breakthrough" };
var mostInteresting = await context.Blogs.OrderBy(x => EF.Functions.FullTextScore(x.Contents, keywords)).Take(5).ToListAsync();

La recherche en texte intégral peut être utilisée avec la recherche vectorielle au sein de la même requête (c’est-à-dire la recherche hybride), en combinant les résultats des fonctions FullTextScore et VectorDistance. Cela peut être fait en utilisant la fonction RRF (fusion de classement réciproque), que EF Core propose également à l'intérieur de EF.Functions:

public class Blog
{
    ...

    public float[] Vector { get; set; }
    public string Contents { get; set; }
}

public class BloggingContext
{
    ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>(b =>
        {
            b.Property(x => x.Contents).EnableFullTextSearch();
            b.HasIndex(x => x.Contents).IsFullTextIndex();

            b.Property(x => x.Vector).IsVectorProperty(DistanceFunction.Cosine, dimensions: 1536);
            b.HasIndex(x => x.Vector).IsVectorIndex(VectorIndexType.Flat);
        });
    }
}

float[] myVector = /* generate vector data from text, image, etc. */
var hybrid = await context.Blogs.OrderBy(x => EF.Functions.Rrf(
        EF.Functions.FullTextScore(x.Contents, "database"), 
        EF.Functions.VectorDistance(x.Vector, myVector)))
    .Take(10)
    .ToListAsync();

Conseil / Astuce

Vous pouvez combiner plus de deux fonctions de scoring dans l'appel Rrf, ou bien utiliser uniquement FullTextScore, ou uniquement VectorDistance.