Une recherche “Full text” devient souvent une nécessité lorsqu’on travaille sur des projets ayant beaucoup de contenu. Différents outils permettent de réaliser ce genre de recherches avec plus ou moins d’efficacité. Pour Rails, il existe bien évidement Ferret, probablement le plus connu, mais aussi Solr basé sur Lucene, Sphinx et enfin, Xapian.
Je n’ai pas la prétention de dire que je suis un expert en la matière mais ayant utilisé Xapian durant le dernier projet sur lequel j’ai travaillé, je me suis dit qu’un petit partage de connaissances s’imposait. Histoire de vous donner les moyens de tester tout ça par vous-même.
Etape 1 : Installer Xapian
Suivant votre OS il existe plusieurs manières d’installer Xapian. Tout est expliqué sur le site de Xapian. Choisissez la manière qui vous convient le mieux. Pour l’exemple on partira des fichiers source !
Télécharger les sources de xapian :
http://oligarchy.co.uk/xapian/1.0.10/xapian-core-1.0.10.tar.gz
Et les bindings qui nous permettrons de l’utiliser avec Ruby :
http://oligarchy.co.uk/xapian/1.0.10/xapian-bindings-1.0.10.tar.gz
Il est bien évidement conseillé d’utiliser la même version pour xapian et ses “bindings”.
1 tar xvzf xapian-core-version.tar.gz 2 tar xvzf xapian-bindings-version.tar.gz 3 4 cd xapian-core-version 5 ./configure 6 make 7 sudo make install 8 9 cd xapian-bindings-version 10 ./configure 11 make 12 sudo make install
Etape 2 : Installer acts_as_xapian
La première chose à faire est de récupérer acts_as_xapian sur github.
1 script/plugin install git://github.com/frabcus/acts_as_xapian.git
Ensuite, d’exécuter les migrations associées.
1 script/generate acts_as_xapian 2 rake db:migrate
Voilà, nous sommes prêts !
Etape 3 : Tous dans le bac à sable
Dans tous les modèles ou vous souhaitez utiliser une recherche “Full text” ajoutez la ligne suivante :
1 class Stuff < ActiveRecord:Base 2 acts_as_xapian :texts => [:title, :description, :tags] 3 end
En remplaçant, bien évidement :title, :description et :tags par les champs de votre modèle dans lesquels vous souhaitez faire la recherche.
Ajoutez quelques objets en db et construisez l’index de recherche en prenant soin de spécifier les modèles (séparés par un espace) pour lesquels il est nécessaire de construire cet index.
1 rake xapian:build_index models="Stuff AutreModel1 AutreModel2"
On peut alors tester la recherche en console :
1 rake xapian:query models=“Stuff AutreModel1 AutreModel2” query=“test”
Qui aura pour effet de rechercher “test” dans les champs renseignés dans le paramètre :texts de acts_as_xapian des trois modèles spécifiés.
Etape 4 : Et dans mon contrôleur ça donne quoi ?
C’est tout simple :
1 @query = ActsAsXapian::Search.new([Stuff], @query_params)
On cherche dans le modèle Stuff avec pour paramètres de recherche @query_params (la chaîne de caractères que l’on veut rechercher).
Pour obtenir les résultats il suffit de faire :
1 @results = @query.results
Attention ! @results n’est pas un tableau d’objets d’un modèle ActiveRecord ! Pour ça, il faut repasser le tout à la moulinette :
1 @stuffs = @results.collect{|r| r[:model]}
Ou pour faire simple et en une seule ligne :
1 @stuffs = ActsAsXapian::Search.new([Stuff], @query_params) 2 .results.collect{|r| r[:model]}
Etape 5 : Et si mes données changent ?
Le seul petit problème d’acts_as_xapian est qu’il ne propose pas de mise à jour automatique de l’index lorsqu’il y a un changement dans les données. Si changement il y a, cette modification est ajoutée à la table acts_as_xapian_jobs que nous avons créée grâce à la migration de l’étape 2. Et ce n’est que lorsque l’on exécute
1 rake xapian:update_index
que les changements sont pris en compte. Vous trouverez plus d’explications en suivant le premier lien à la fin de cet article. Qu’avons-nous fait dans notre dernier projet ? Une simple tâche cron, qui est appelée toutes les x minutes et qui met à jour l’index. Une autre qui s’exécute une fois par jour pour reconstruire complètement l’index.
Etape 6 : Et maintenant ?
Plusieurs autres possibilités sont présentes dans acts_as_xapian, comme la recherche par ‘terms’, ou encore la possibilité de proposer des corrections ou des alternatives à la recherche effectuée.
Notre introduction s’arrête malheureusement là, mais les quelques liens suivants vous serons sûrement très utiles :
Très bon article, un petit bémol toutefois concernant Xapian, le fait qu’il n’index pas en live peut suivant les projets être très gênant et dans ce cas seul Ferret reste une solution viable…