Sphinx est un serveur de recherche full text permettant d’indexer et de rechercher dans des données stockées soit dans des bases de données SQL, no SQL ou alors dans un système de fichiers.
Il peut facilement s’intégrer à une application Ruby On Rails via la gem Thinking Sphinx. On définit alors dans les modèles tous les attributs qui doivent être indexés. Cela fonctionne parfaitement lorsque notre application utilise une seule et unique locale.
Prenons l’exemple d’une application dans laquelle nous avons défini un modèle Actuality :
[ruby]
class Actuality < ActiveRecord::Base
validates :title, :presence => true
validates :body, :presence => true
define_index do
indexes :title
indexes :summary
indexes :body
set_property :delta => true
end
end
[/ruby]
Que se passe-t’il donc lorsque l’application développée est internationalisée et que les traductions des contenus stockés en base doivent être indexés par locale ?
Avant d’arriver au résultat final, jetons un coup d’oeil rapide sur la gestion de la traduction des contenus.
Nous utilisons pour cela la gem Globalize3 qui permet de stocker les traductions de certains attributs d’un modèle dans une table à part.
[ruby]
gem ‘globalize3’ # à placer dans le Gemfile
[/ruby]
Ensuite, il faut indiquer au modèle Actuality à qui nous allons traduire un certain nombre de ces attributs
[ruby]
class Actuality < ActiveRecord::Base
translates :title, :body
validates :title, :presence => true
validates :body, :presence => true
define_index do
indexes :title
indexes :body
set_property :delta => true
end
end
[/ruby]
Pour finir, il faut modifier la structure de la base de données pour ajouter la table contenant les attributs traduits
[ruby]
class AddTranlationsToActualities < ActiveRecord::Migration
def self.up
Actuality.create_translation_table! :title => :string, :body => :text
end
def self.down
Actuality.drop_translation_table!
end
end
[/ruby]
Maintenant que les attributs title et body d’Actuality sont traduits via Globalize3, nous pouvons définir les index associés à chaque locale en précisant que les attributs qui doivent être indexés sont ceux de la table translations associée à notre modèle et que nous utilisons un filtre de sélection différent pour chaque locale :
[ruby]
class Actuality < ActiveRecord::Base
translates :title, :body
validates :title, :presence => true
validates :body, :presence => true
define_index(‘actuality_fr’) do
indexes translations.title, :as => :title
indexes translations.body, :as => :body
where "actuality_translations.locale=’fr’"
set_property :delta => true
end
define_index(‘actuality_de’) do
indexes translations.title, :as => :title
indexes translations.body, :as => :body
where "actuality_translations.locale=’de’"
set_property :delta => true
end
end
[/ruby]
Désormais comment utiliser les nouveaux index définis ? Nous pouvons tout simplement indiquer à la méthode search sur quel index rechercher.
[ruby]
Actuality.search "*#{q}*" , :index => "actuality_fr"
Actuality.search "*#{q}*" , :index => "actuality_de"
[/ruby]
En conclusion, il est possible très simplement dans Rails3 de créer un moteur de recherche basé sur Sphinx et recherchant des contenus en fonction de la locale de l’utilisateur.
Auteur : Michaël Mithouard
Ajouter un commentaire