13 décembre 2013

Couchbase - Effectuer des recherches

Couchbase dispose, au travers des vues, d'une fonctionnalité d'indexation sur les documents qui permet une récupération très rapide des informations des documents.

Nous verrons dans cet article comment définir les indexations des documents à l'aide des vues et comment en récupérer les résultats. Nous verrons cela à l'aide d'un projet Java.

Fonctionnement de l'indexation

Pour effectuer une recherche, nous avons besoin dans Couchbase de créer une vue qui est en fait un indexeur de documents.

La recherche s'appuie sur les informations stockées dans l'index lié à cette vue et non sur les documents eux-mêmes.

La vue a pour rôle de décrire comment cet index est construit :
  • sur quels documents ? 
  • avec quelles informations de ces documents ?

Pour cela, la vue dispose des deux fonctions map et reduce de la vue qui servent à décrire et à construire cet index.



La fonction map filtre les documents et ne sélectionne qu'une partie de leurs informations. Nous pouvons ainsi sélectionner que les documents de type Livre et de n'en conserver que l'auteur, le titre et l'année de publication.

La fonction reduce permet d'appliquer des règles de calcul sur les informations retournées par la fonction map.

La  fonction reduce n'est pas obligatoire:
  • Si la fonction reduce n'est pas définie, c'est le résultat de la fonction map qui est stocké dans l'index. 
  • Si la fonction reduce est définie, c'est le résultat de cette fonction qui est stocké dans l'index.

Une fois la vue créée, l'index peut être construit par Couchbase.

Pour la recherche, nous appelons cette vue pour utiliser son index et effectuer ainsi une recherche sur les informations stockées dans cet index.

Une des problématiques portera sur les stratégies de mise à jour de cet index. En effet, dans Couchbase tout est asynchrone et l'index n'est pas mis à jour lors de l'insertion d'un nouveau document. Par conséquent, nous n'avons pas toujours un index à jour par rapport aux documents qui viennent d'être insérés ou supprimés.

Voyons pour le moment un exemple de recherche dans Couchbase.

Exemple de vue

Prenons comme exemple de base de données : une librairie.

Cette base contient des documents multiples et nous ne souhaitons récupérer que les documents qui sont des livres. Ces documents ont comme identifiant la forme suivante : book_[id], avec [id] le numéro d'identifiant du livre.

Voici un exemple de document Livre :

Pour récupérer tous les livres, nous créons une vue nommée searchBook pour indexer les documents de type Livre. Pour cela, nous définissons cet index à l'aide de la fonction map de la vue pour sélectionner les livres :



La fonction map a deux paramètres :
  • doc : les informations d'un document à indexer
  • meta : les informations spécifiques à Couchbase sur ce document, comme son identifiant système

Dans l'exemple ci-dessus, nous utilisons son identifiant récupéré via meta.id pour filtrer les documents de type Livre en vérifiant que l'identifiant commence par book_.

La fonction emit indique ce qui est indexé dans l'index de la vue.
  • Le premier paramètre indique les informations qui vont servir de clé d'indexation et de recherche. Ce peut être un tableau composé de plusieurs valeurs (voir exemple).
    • Dans notre exemple, nous stockons comme clé d'index l'année de publication du livre. Ceci nous permettra de restreindre les livres lors de la recherche sur une plage d'années de publication.
  • Le deuxième paramètre contient les valeurs liées à la clé d'indexation. Ces valeurs pourront par exemple servir pour l'affichage sans avoir à charger tout le document. Ce peut être un tableau de plusieurs valeurs (voir exemple). 
    • Dans notre exemple, nous y stockons l'auteur et le titre du livre.

Par défaut, la recherche retourne toujours la clé d'indexation et les valeurs associées.
En plus de cela, Couchbase nous donne la possibilité de récupérer ou non le document associé en même temps dans les résultats de la recherche.

Projet Java

A partir de notre exemple, nous allons créer un projet Java pour tester la recherche :
  •  Vous devez voir les livres suivants :
Livres

Créer la vue pour l'index de recherche

Nous pouvons créer la vue soit via l'interface d'administration, soit via le code Java.


Via l'interface d'administration :
  • Aller sur localhost:8091/index.html#sec=views
  • Cliquer sur Add View
  • Saisir un nom à la fin du champ Design Document Name, sans supprimer ce qu'il y a au début du champ
  • Saisir le nom de la vue dans le champ View Name 
  • Cliquer sur Save 
  • La vue a été créée et est visible dans la liste des vues
  • Cliquer sur le bouton Edit lié à cette vue dans la liste
  • La page de la vue s'affiche avec :
    • à gauche la saisie de la fonction map
    • à droite la fonction reduce
  • Après modification d'une de ces deux fonctions, vous devez cliquer d'abord sur Save puis sur Show Results pour voir le résultat de la recherche, c'est à dire ce qui a été stocké dans l'index de la vue

Via le code :
  • Dans notre projet, dans le répertoire src/test/java, créer la classe Java CreateViewSearchBook suivante :

  • Lancer l'exécution de ce test pour créer la vue dans la base Couchbase
  • Aller à l'adresse suivante : localhost:8091/index.html#sec=views
  • Cliquer sur le bouton Production Views
  • La vue searchBook apparaît dans cette liste
  • Cliquer sur le bouton Show
  • La page de consultation de la vue apparaît et nous pouvons voir les fonctions map et reduce de cette vue
  • Cliquer sur le bouton Show Results pour tester la vue : les 5 livres doivent apparaître

Utiliser la vue en Java

Cette vue va nous servir à récupérer les documents de type Livre.

Nous utilisons l'objet Query pour indiquer :
  • setLimit(nb): limite le nombre d'éléments retournés
  • setRange(keyStart, keyEnd): indique la valeur minimale et maximale de la clé d'index
    • Dans notre exemple, nous voulons les livres parus entre 2005 et 2008
  • setIncludeDocs(true) : indique que le document associé à l'élément retourné est fourni dans les résultats de la recherche
  • setStale(false) : indiquer si l'index doit être mis à jour avant le lancement de la recherche. Ceci entraîne une attente du client pendant que Couchbase mette à jour les index en attente. 
    • Attention: l'indexation ne s'effectue que sur les documents réellement persistés dans la base Couchbase et non ceux encore dans la mémoire vive de la base.

La méthode query de l'objet CouchbaseClient permet de lancer la recherche et de récupérer les résultats.
Elle prend en paramètre :
  • le nom de la vue 
  • l'instance de Query.

Cette méthode retourne une instance de ViewResponse qui contient la liste des résultats.

Pour chaque élément ViewRow contenu dans ViewResponse, nous avons les méthodes suivantes :
  • getKey() : retourne la clé d'indexation (premier paramètre de emit dans la fonction map)
  • getValue() : retourne les valeurs liées (deuxième paramètre de emit dans la foncton map)
  • getId() : retourne l'identifiant du document
  • getDocument() : retourne le contenu du document, uniquement si setIncludeDocs(true) a été définie sur l'objet Query

Dans notre projet Java :
  • Créer la classe Java de test pour rechercher les livres et charger les objets Livre en Java :

  • Lancer ce test
  • Le contenu de la console d'exécution contient la liste des livres

 Conclusion


Nous venons de voir le principe des vues et des index dans Couchbase et comment effectuer une recherche dans Couchbase.

Le fait de définir une valeur minimale et maximale sur la clé d'indexation permet de restreindre le résultat de la recherche.

Cependant, cela ne permet pas d'avoir une recherche aussi avancée que sur une base classique.

C'est pourquoi Couchbase développe le futur module N1QL qui permettra d'effectuer des recherches avec la même syntaxe SELECT .. FROM ... WHERE ... que SQL.

Voici d'ailleurs une page de démonstration de N1QL pour tester l'écriture de requêtes de type SQL sur Couchbase :
Il est également possible de l'installer comme module de Couchbase pour le tester et d'utiliser des URL REST pour effectuer une recherche avec la syntaxe SQL.

Le module N1QL semble déjà très prometteur et permettra sûrement une encore plus large adoption de Couchbase.