Implémentation d’une solution fondée sur les Azure App Services : Mise en œuvre du service de recherche

Voici donc le deuxième d’une série d’articles consacrée à l'implémentation d’une solution fondée sur les Azure App Services et qui sera organisée de la façon suivante :

 

Azure Search Service

« Azure Search » est un service Cloud qui facilite l'ajout de fonctions de recherche à un site web ou une application. Ce service est fondé sur le moteur de recherche Elasticsearch. Il offre donc la recherche « full-text », ainsi que des fonctions plus avancées telles que les suggestions de requête basées sur une saisie partielle, le surlignage et la navigation à facettes. Il intègre le support du langage naturel, en appliquant des règles linguistiques fonction de la langue spécifiée. Enfin, et surtout, il est entièrement géré. Cette approche « Search as a Service » élimine la complexité liée à la configuration ainsi qu’à la gestion d’un index de recherche et permet de bénéficier d’une haute disponibilité sur le service, de son adaptation à la charge (capacité de stockage et de recherche) et des mises à jour du moteur.

Déploiement et configuration du service de recherche

La configuration du service « Azure Search » est réalisée depuis le nouveau portail Azure. Chaque service est unique avec un nom correspondant à son url. Par exemple, pour le service « stephgou », l’url est : « https://stephgou.search.windows.net ».

image

Pour utiliser la fonction recherche d'Azure, il faut d’abord créer une instance du service en indiquant sur quel DataCenter elle va s'exécuter et quelle capacité elle devra fournir. Une fois cette instance créée, elle est exposée via son interface REST ou via le SDK .NET. Une API Node.js est également en cours de développement sur GitHub : https://github.com/azure-contrib/node-azure-search.

Définition de l’index

Pour commencer, il est nécessaire de définir un ou plusieurs indexes. Chaque index contient les informations accessibles à une demande de recherche. L’index apparaît donc comme une collection consultable de documents. Il est doté d’un schéma décrit en JSON et peut avoir beaucoup d'attributs.
Chaque attribut peut avoir plusieurs propriétés telles que nom, type de données  (string, Int, datetime, …) ainsi que différentes options que l’on peut activer ou non sur ces champs :

  • « Key » : identifiant unique de l’enregistrement dans l’index
  • « Searchable » : recherche full-text
  • « Filterable » : support pour les requêtes complexes (format OData)
  • « Retrievable » : obtention de la valeur du champ après la recherche
  • « Sortable » : tri sur le champ
  • « Suggestions » : mode « autocomplete »

A ces attributs peuvent s’ajouter des compléments comme un niveau de ranking par exemple. Chaque index est unique avec un nom correspondant à son url. Par exemple, pour l’index « thot » créé sur le service « stephgou », l’url est : « https://stephgou.search.windows.net/indexes/thot ». L’index contient uniquement des documents structurés selon le modèle de recherche spécifique souhaité (et défini dans l’index). On peut le créer depuis le nouveau portail Azure. 

image

On peut également le créer avec l’API. Pour utiliser le SDK.NET,  il suffit de référencer la librairie « Microsoft.Azure.Search ». On peut alors utiliser la classe « SearchServiceClient » qui offre la possibilité de créer, modifier, supprimer, des définitions d’index.

image

Le code C# suivant, extrait du projet « BuildIndex.Search.App » est celui employé pour automatiser la création de ce même index.  
image
Enfin, on peut aussi le créer via un simple PUT HTTP avec un outil comme Fiddler. Une fois l’index créé, on peut interroger son statut avec l’API REST. Par exemple, la requête suivante m’indique que l’index « thot » contient 6 documents et occupe 8660 octets.
https://stephgou.search.windows.net/indexes/thot/stats?api-version=2015-02-28 

image

Indexation des données

Un index doit contenir des données avant de pouvoir être utilisé par une application. Azure Search Service permet nativement d’indexer le contenu de sources de données Azure SQL Database ou DocumentDB, mais pas le stockage Azure.

image
Il faut donc « pousser » le contenu que l’on souhaite rendre accessible à la recherche pour l’indexer. Pour ce faire, on peut utiliser l’interface REST (via un POST http) ou le SDK. Les données sont indexées par batchs, par paquet de maximum 1000 opérations (upload, merge, delete ou mergeOrUpload). L’appel client doit valider individuellement les statuts des réponses HTTP pour chaque opération. Dans notre cas, l’index est initialisé en fonction des documents déjà présents dans le stockage Azure, puis il est mis à jour à chaque nouvelle publication via le code C# suivant, comme l’illustre cet extrait du projet « Doc.Search.Portal » :

image 
… 
image

Le statut de l’indexation en termes de nombre de documents et stockage peut être consulté directement depuis le nouveau portail.
 
image

Recherche

Une fois l’index créé et initialisé, il est possible de l’interroger. Pour se faire, il est possible, là aussi, d’utiliser une API REST ou le SDK.NET. La portée de la recherche est limitée à un seul index. L’API offre de multiples options. La recherche « full-text » supporte l’utilisation des opérateurs « classiques », tels que « orderby », « top »,… et permet ainsi l’application de filtres, la pagination et la sélection de champs.
Par exemple, la requête suivante permet de récupérer tous les documents contenus dans l’index :
https://stephgou.search.windows.net/indexes/thot/docs?api-version=2015-02-28
Pour la filtrer, il suffit d’ajouter le paramètre sur lequel on souhaite effectuer cette sélection :
https://stephgou.search.windows.net/indexes/thot/docs?api-version=2015-02-28&name=A
Cette requête peut-être directement exécutée depuis « Fiddler » (ce qui suppose de renseigner la clé de l’API dans les entêtes de la requête). 

image
Le résultat de cette requête est présenté dans la copie d’écran suivante. 

image
On peut également effectuer ces recherches avec l’API. La librairie « Microsoft.Azure.Search » propose la classe « SearchIndexClient » qui permet d’effectuer une recherche « full-text » ou une recherche filtrée en fonction d’un élément renseigné dans l’index.imagePour ajouter un filtre, il suffit de renseigner un « SearchParameter ». Par exemple, pour limiter la recherche aux documents Word, il suffit d’appliquer un filtre sur la propriété « content_type ».imageLe code C# permettant d’exécuter une requête sur l’index est extrêmement simple, comme l’illustre la fonction suivante, extraite du projet « BuildIndex.Search.App » :  imageNotre service backend de recherche est maintenant opérationnel. Dans le prochain article, nous verrons comment consommer le service « Azure Search » depuis une application Web.