Comme pour la recherche vectorielle dans la section précédente, vous apprendrez dans cette section à combiner les meilleurs résultats de recherche en texte intégral et sémantique à l'aide de l'algorithme Reciprocal Rank Fusion.
Introduction aux sous-recherches
La solution pour mettre en œuvre une recherche hybride en texte intégral et en vecteur dense a consisté à envoyer une demande de recherche comprenant les arguments query, knn pour demander les deux recherches, et l'argument rrf pour les combiner en une seule liste de résultats.
La complication qui se présente lorsque l'on essaie de faire la même chose pour combiner les requêtes de recherche en texte intégral et de recherche vectorielle éparse est que les deux utilisent l'argument query. Pour pouvoir fournir les deux requêtes qui doivent être combinées avec l'algorithme RRF, il est nécessaire d'inclure deux arguments query, et la solution consiste à utiliser des sous-recherches.
Les sous-sélections sont une fonctionnalité qui est actuellement en avant-première technique. C'est pourquoi le client Python Elasticsearch ne le prend pas en charge de manière native. Pour contourner cette limitation, la méthode search() de la classe Search peut être modifiée pour envoyer la requête de recherche en utilisant l'argument body. Vous pouvez voir ci-dessous une nouvelle implémentation similaire qui utilise l'argument body du client pour envoyer une requête de recherche :
Cette mise en œuvre ne nécessite aucune modification de l'application, puisqu'elle est fonctionnellement équivalente. La seule différence est que la méthode search() valide tous les arguments avant d'envoyer la requête, body étant la seule exception. Le serveur valide toujours les demandes, quelle que soit la manière dont le client les envoie.
Avec cette version, l'argument sub_searches peut être utilisé dans Search.search() pour envoyer plusieurs requêtes de recherche comme suit :
Mise en œuvre de la recherche hybride
Pour terminer cette section, reprenons la logique du texte intégral et combinons-la avec la requête de recherche sémantique présentée plus tôt dans ce chapitre.
Ci-dessous, vous pouvez voir le point de terminaison handle_search() mis à jour :
Comme vous vous en souvenez, la fonction extract_filters() recherchait les filtres de catégorie saisis par l'utilisateur dans l'invite de recherche et renvoyait la partie restante sous la forme parsed_query. Si parsed_query est vide, cela signifie que l'utilisateur n'a saisi qu'un filtre de catégorie et, dans ce cas, la requête doit être un simple match_all avec la catégorie sélectionnée comme filtre. Ceci est mis en œuvre dans la partie else du grand conditionnel.
Lorsqu'il existe une requête de recherche, l'option sub_searches est utilisée comme indiqué dans la section précédente pour inclure les requêtes multi_match et text_expansion, l'option rank demandant que les résultats des deux sous-recherches soient combinés en une seule liste de résultats classés. Pour compléter la requête, les arguments size et from_ sont fournis pour maintenir la prise en charge de la pagination.
Cliquez ici pour consulter cette version de l'application.
Précédemment
Requêtes sémantiquesSuivant
Conclusion