Azure Search Service

Cet article est le premier d’une série qui sera consacré à un nouveau service mis en place au niveau de Microsoft Azure, j’ai nommé Microsoft Azure Search Service. Ce service permet, comme son nom l’indique, de mettre en place un service de recherche au sein de son site Web ou de son application. Au cours de ce premier article, nous ferons un tour d’horizon des possibilités offertes par ce nouveau service, et nous mettrons en place notre première instance de service avec une petite application qui consommera ce service. Dans les articles suivants nous rentrerons un peu plus dans les détails. Bon maintenant que les présentations sont faites je vous propose d’entrer dans le vif du sujet.

1-  Présentation générale

Le service de recherche Azure permet de mettre en place de manière simple un service de recherche full-text qui pourra être utilisé par n’importe quel type d’application. En plus de ces fonctionnalités de base, le service de recherche Azure permet de mettre en place des profiles de scoring permettant d’avoir une incidence sur les résultats de la recherche (ex : mettre en avant une liste de produits en promotion), ou encore la mise en place de mécanismes de suggestions. Au niveau architecture, ce service est composé principalement d’un Index, qui est l’objet à partir duquel s’effectue les recherches. Cet index, défini à partir d’un ensemble de propriétés, est alimenté pour une ou plusieurs sources de données. Le schéma suivant permet d’avoir une vue globale de l’architecture. blog ai3 ArchitectureGlobale-300x133 Azure Search Service Afin de pouvoir interagir avec le service vous pouvez soit directement passer par l’API REST exposée par le service, soit passer par un des SDK fournit par les équipes Microsoft. Au moment de l’écriture de cet article un SDK est disponible pour les plateformes .NET, Java, et NodeJS.

1.1-  Index et documents

Un index est l’élément de base du service de recherche, c’est sur ce composant que s’effectueront les recherches. Un index est défini par un schéma, et est composé d’une collection de documents, que l’on peut assimiler à des lignes dans une base de données. Chaque document est conforme au schéma défini lors de la création de l’index (noms de champs, types de données et propriétés). Le schéma d’un index est composé d’une liste de propriétés représentant les différents éléments sur lesquels pourront s’effectuer les recherches. Chaque propriété d’un index est définit par un type (int, string, geopoint, bool …) et par des attributs qui vont définir les capacités de chacune des propriétés au niveau de l’index. La liste de ces attributs est la suivante :

  • Name : décrit la donnée contenue par ce champ.
  • Type : définit le type du champ (valeur possible : string, int32, double, booléen …). Il est à noter que le type géo spatial est également présent au niveau des types supportés, ce qui permet notamment la mise en place de recherche se basant sur la localisation de l’utilisateur
  • Searchable : permet de définir si un champ peut être pris en compte par une recherche.
  • Suggestion : permet de définir ce champs comme pouvant être utilisé lors de la recherche de suggestions.
  • Sortable : indique si une recherche peut être triée à partir de ce champ
  • Retriveable : indique si ce champ peut être remonté dans un résultat de recherche
  • Filterable : indique si ce champ peut être utilisé en tant que filtre.
  • Facetable : lorsque cette propriété est activée, elle indique que le champ en question pourra être utilisé pour retourner le nombre d’éléments concerné par une requête de recherche.

1.1.1-  Approvisionnement d’un index

Comme expliqué précédemment un index est composé d’un ensemble de documents. Lors de la création d’un index, celui-ci ne contient aucun document, il faut donc mettre en place l’approvisionnement de celui-ci avec les informations sur lesquelles nous désirons mettre en place nos recherches. Au niveau du service de recherche deux possibilités s’offrent à nous :

  • Approvisionnement via l’API REST, dans ce cas nous utiliserons les possibilités offertes par l’API REST pour pouvoir alimenter notre index. Pour utiliser cette API vous pouvez soit passer par un des SDK (le plus simple) proposé par les équipe de Azure Search (.NET, Java, NodeJS), soit passer directement par l’API REST. Nous verrons un peu plus tard comment utiliser cette méthode.
  • Approvisionnement via l’utilisation d’un indexer. Un indexer peut être vu comme un connecteur à une source de données, qui va nous permettre de nous connecter à une source de données pour alimenter notre index. Au moment de l’écriture de cet article les deux seules sources de données disponibles sont Azure SQL Database et DocumentDB.

Noté que quelque soit la méthode employée, les données importées devront respecter le schéma définit au niveau de l’Index.

1.2-  Partitions et réplicas

Comme la plupart des services proposés au niveau de Azure la prise en compte des problématiques de haute disponibilité, de fee sont prises en compte (paramètres non disponibles pour la version gratuites). En cas de dépassement de capacité en termes de volumétrie ou en termes de nombre de documents au niveau d’un index, il est possible de mettre en place des partitions au niveau de celui-ci. Chaque partition aura les mêmes capacités que celles exposées par la partie de base d’un index (soit 25 Gb d’espace disque ou 15 millions de documents pour une partition en mode standard) Pour avoir toutes les informations concernant les limites et les contraintes liées à la version de service que vous désirez utiliser vous pouvez vous rendre à l’adresse suivante : https://msdn.microsoft.com/en-us/library/azure/dn798934.aspx Pour la gestion de la haute disponibilité et de la scalabilité de votre index il est possible d’utiliser des replicas. un replica peut être vu comme une instance de votre index, chacun des replicas sera composé de l’ensemble des partitions définie au niveau de votre index de base. Si par exemple vous créer un index avec 4 partitions, si vous créer ensuite un réplica, celui-ci sera composé des copies des 4 partitions, vous index sera alors composé de 8 unités de recherche (8 SU). Pour avoir les idées un peu plus clairs vous pouvez voir au niveau de l’image ci-dessous une instance de service composé de 2 index (index1, index2), avec pour chacun un certain nombre de partitions et de réplicas. blog ai3 Replicas_1-300x153 Azure Search Service   Au niveau Azure Serch Service, une partition ou un replica est vu comme une unité de recherche, et une instance de service ne peut contenir plus de 36 unités de recherche. Afin de ne pas se retrouver bloqué par cette limitation, il est important lors de la mise en place de votre instance de bien réfléchir à la répartition de vos unités de recherche entre partition et replica.

1.3-  Gestion des accès

Afin de gérer les accès au service de recherche, celui-ci s’appuie sur un mécanisme de clés, avec différents niveau d’accès. Pour tout accès au service se faisant via l’API REST, une clé d’accès doit être positionnée au niveau de la requête. 2 types de clés sont gérées au niveau du service de recherche :

  • Clé d’administration permettant d’avoir un accès complet à l’API exposée par le service. Ce type de clé permet entre autre de créer des index, de mettre en place des indexers …
  • Clé de requête, permettant d’avoir accès à la partie recherche exposé par l’API, c’est ce type de clé qui sera utilisée par les applications pour effectuer les recherches.

Il est à noter que le nombre maximum de clés d’administration et fixé à deux par instance de service, et que le nombre maximum de clés de requête et fixé à 50 par instance de service. La gestion de ces clés se fait au niveau de l’interface d’administration au niveau du portail Azure en mode Preview. Bon maintenant que nous avons vu tout l’aspect théorique je vous propose de passer à un peu de pratique.

2-      Mise en pratique

Après toute cette théorie voici venu le temps de la mise en pratique. Dans la suite de cet article je vous propose de mettre en place une instance de service de recherche, et ensuite de mettre en place une application console qui consommera notre service. Pour ce faire nous allons procéder par étape, et la première sera de créer notre instance de service. Pour mener à bien cette partie il vous faut avoir un abonnement Microsoft Azure, si ce n’est pas le cas, vous pouvez toujours vous en procurer un à l’adresse suivante http://azure.microsoft.com/fr-fr/pricing/free-trial/?WT.mc_id=A49671BA7 (accès gratuit pendant 30 jours avec un seuil de dépense comprit de 150 euros).

2.1- Création d’une nouvelle instance de service

Pour pouvoir créer votre instance de service de recherche, veuillez-vous connecter sur la version Preview du portail d’administration Azure. Ensuite cliquer sur nouveau et sélectionner Data+Storage au niveau du menu de création, et ensuite sélectionner Recherche comme montrer dans la capture d’écran suivante.   blog ai3 CreationServiceStep1-300x297 Azure Search Service   Renseigner ensuite les différentes informations nécessaires. Une fois terminée cliquer sur Créer. blog ai3 CreationServiceStep2-201x300 Azure Search Service

2.2-     Création de notre premier index

Nous allons créer un index qui va nous permettre de faire des recherches sur des informations concernant des hôtels. Cet index servira de base pour la suite de cet article mais aussi pour les articles suivants. Pour pouvoir créer votre index, ouvrez l’instance de service que vous venez de créer. Au niveau de menu, contenu au niveau du bandeau du haut, sélectionner Ajouter un index, et entrez comme nom d’index hotels. blog ai3 CreationIndexStep1-300x298 Azure Search Service

2.2.1-  Création du schéma

Créez ensuite le schéma de votre index comme dans l’image ci-dessous. blog ai3 CreationIndexStep2-300x243 Azure Search Service   Dès que vous aurez saisi toutes les informations concernant votre index cliquez sur le bouton OK afin de procéder à la création de celui-ci. Une fois créé vous devriez avoir accès à un panneau d’informations concernant votre index comme dans l’image ci-dessous. blog ai3 CreationIndexStep3-190x300 Azure Search Service   Maintenant que notre index est créé, nous allons pouvoir passer à l’approvisionnement de celui-ci.

2.3-     Approvisionnement de notre index

Afin de pouvoir approvisionner notre index nous allons passer par Fiddler, il est aussi possible de le faire en utilisant le sdk, mais je voulais montrer au travers de cette partie comment utiliser Fiddler pour interagir avec l’API Search. Pour pouvoir composer des requêtes avec Fiddler il faut passer par le modeleur proposé par celui-ci, pour se faire choisissez l’option F9. Au niveau de l’URL à saisir elle se compose comme ceci: https://<nomDuServiceDeRecherche>.search.windows.net/indexes/<nomDeMonIndex>/docs/Index?api-version=2015-02-28 Au niveau des Headers à positionner, ceux-ci sont au nombre de deux : content-type permettant de définir le contenu de notre requête, dans notre cas cela sera application/json api-key permettant de passer la valeur de l’une des clé d’administration de notre service de recherche<adminSearchKey> Pour pouvoir renseigner la valeur du paramètre API Admin Key il vous faut vous connecter au portail Azure et récupérer la valeur de l’une des deux clé d’administration associé à votre service de recherche. Ensuite au niveau du body de la requête copier juste le contenu ce dessous contenant les informations (documents) que nous allons ajouter à notre index.

[pastacode lang= »javascript » message= » » highlight= » » provider= »manual »]

{ "value": [ {"@search.action": "upload", "id": "1", "nom": "Park & Suites Prestiges", "pays": "France","ville":"Toulouse", "categorie":"4", "coordonnees": { "type": "Point", "coordinates": [-43.6219068,1.3592439] },"adresse":"10 Place de la Révolution 31700 Blagnac","nbchambreslibres":12,"prestations":"piscine,salle de sports,spa","prix":"213.10","promo":"false","image":"http://d1pa4et5htdsls.cloudfront.net/images/vfml/1/1/5/0/3/2/7/a2e51859_exterior_s-original.jpg"}, {"@search.action": "upload", "id": "2", "nom": "Holiday Inn", "pays": "France","ville":"Toulouse", "categorie":"4", "coordonnees": { "type": "Point", "coordinates": [-43.6219068,1.3592439] },"adresse":"1 Place de la Révolution 31700 Blagnac","nbchambreslibres":36,"prestations":"piscine,spa","prix":"148.00","promo":"true","image":"http://hitoulouseairport.com/wp-content/uploads/2013/10/1402-05_holidayinn_blagnac_chambre_5_web.jpg"}, {"@search.action": "upload", "id": "3", "nom": "Radisson Blu Hotel ", "pays": "France","ville":"Toulouse", "categorie":"3", "coordonnees": { "type": "Point", "coordinates": [-43.6204466,1.3134532,13] },"adresse":"2 Rue Dieudonné Costes 31700 Blagnac","nbchambreslibres":2,"prestations":"tennis","prix":"98.00","promo":"true","image":"http://www.idealseminaire.fr/images/hotels/14951/8.jpg"} ] }

[/pastacode]

Vous pouvez alors exécuter la requête, n’oubliez pas de passer la requête en mode POST. blog ai3 FiddlerRequest-300x160 Azure Search Service Si tout se passe bien vous devriez avoir un résultat avec un code retour 200,proche de celui de l’image ci-dessous. blog ai3 InsertionFiddlerResult-300x154 Azure Search Service

2.4-     Mise en place de notre application exemple

La solution que nous allons mettre en place sera composée de 4 projets :

  • Un projet appelé Model qui contiendra la classe Hotel et qui nous permettra de pouvoir travailler avec les résultats de nos requêtes de recherche. il est à noter que cette classe reprend les mêmes propriétés que celle que nous avons définies lors de la création de notre Index.
  • Un projet nommé MyApp.Search.Interfaces qui contiendra tous les contrats concernant les différents services utilisés dans le cadre de notre application. dans notre cas, ce projet contiendra une seule interface définissant le contrat pour notre service de consommation de l’API REST du service de recherche Azure.
  • Un projet nommé MyApp.Search.Services qui contiendra l’implémentation du service défini au niveau de notre interface.
  • Un projet appelé ConsoleApp qui contiendra l’application console qui consommera notre service de recherche.

Il est à noter que les projets Model, MyApp.Interfaces, et MyApp.Services.Implémentations sont de type PCL. Cela nous permettra de pouvoir utiliser ces différents projets dans différents types de projets (WebApp, application WPF, application W8,application Xamarin …) sans avoir à réécrire de code. Le code source de cette application est disponible sur GitHub à l’adresse suivante : A noter que cet exemple est pleinement fonctionnel.

2.4.1-   Création de la solution

Dans un premier temps, nous allons créer une solution vide et allons ajouter les projets au fur et à mesure.

2.4.2-   Projet Model

[pastacode lang= »java » message= »Classe Hotel » highlight= » » provider= »manual »]

public class Hotel { public int Id { get; set; } public string Nom { get; set; } public string Pays { get; set; } public string Ville { get; set; } public GeographyPoint Coordonnes { get; set; } public string Image { get; set; } public int NbChambresLibre { get; set; } public double Prix { get; set; } public bool Promo { get; set; } public string Adresse { get; set; } public string Categorie { get; set; } public string Prestation { get; set; } }

[/pastacode]

 

NB : Pour pouvoir gérer le type GeographyPoint vous devez ajouter le package nugget Microsoft.Spatial

2.4.3-   Projet interface de service

Ce projet contient une interface ISearchService qui va exposer les différentes méthodes que nous allons implémenter au niveau de notre service de recherche. De un premier temps, cette interface ne définira qu’une seule méthode SearchHotels qui renvoie une liste d’objet de type Hotel à partir d’un texte passé en paramètre de la méthode.

[pastacode lang= »java » message= »Interface ISearchService » highlight= » » provider= »manual »]

public interface ISearchService { List<Hotel> SearchHotels(string searchText, string filter = null); }

[/pastacode]

2.4.4-   Projet de service

la classe SearchService permet de mettre en place une implémentation de l’interface ISearchService. Au niveau de la méthode SearchHotels() on commence dans un premier par instancier une nouvelle instance de la classe SearchServiceClient qui va permettre de se connecter sur notre instance de service. Ensuite nous allons instancier une nouvelle instance de la classe SearchIndexClient permettant elle de se connecter à notre index. C’est cette instance de classe qui nous allons ensuite utiliser pour effectuer nos recherche via l’utilisation de la méthode générique Search().

[pastacode lang= »java » message= »SearchService.cs » highlight= » » provider= »manual »]

public List<Hotel> SearchHotels(string searchText, string filter = null) { List<Hotel> hotels = new List<Hotel>(); //Instanciation de la classe SearchServiceClient avec en paramètre le nom de notre instance de service // et une clé de type recherche permettant d'effectuer des recherches sur notre instance de service var serviceClient = new SearchServiceClient(_searchServiceName, new SearchCredentials(_apiKey)); //Instanciation de la classe SearchIndexClient avec en paramètre le nom de l'index sur lequel nous //Désirons faire nos recherches SearchIndexClient indexClient = serviceClient.Indexes.GetClient(_searchIndexName); var searchParameters = new SearchParameters(); if (!String.IsNullOrEmpty(filter)) { searchParameters.Filter = filter; } //Lancement de la recherche DocumentSearchResponse<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, searchParameters); //Traitement des résulats foreach (SearchResult<Hotel> result in response) { hotels.Add(result.Document); } return hotels; }

[/pastacode]

2.4.5-   Application console

Au niveau de l’application, je vous éviterez la mise en place de l’injection de dépendance, en instanciant directement une instance de type ISearchService. Ensuite au niveau de l’application l’utilisation de la méthode SearchHotels() permet d’effectuer des recherches sur notre index.

[pastacode lang= »markup » message= »Programm.cs » highlight= » » provider= »manual »]

static void Main(string[] args) { ISearchService searchService = new SearchService(); var hotels = searchService.SearchHotels("toulouse"); var prestiges = searchService.SearchHotels("Place de la Révolution"); } }

[/pastacode]

3-      Conclusion

Ce premier article nous a permis de faire un tour d’horizon des fonctionnalités offertes par Azure Search Service et de mettre en place notre première instance de service. Dans les articles futures nous continuerons notre découverte de ce service avec notamment la mise en place d’un indexer vers une source de données, stay tuned.   David Moïsa.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.