Prime Impressioni su Sphinx
Per la prima volta ho avuto modo di testare funzionamento di Sphinx, uno dei più popolari motori di ricerca full-text in circolazione. L'ho preferito a Lucene per evitare il disagio di Java, e a Ferret per la maggiore affidabilità che mi sembrava dare dal punto di vista del supporto e della stabilità.
Installazione
L'installazione è stata incredibilmente semplice e rapida con homebrew:
brew install sphinx
In realtà mi sono reso presto conto che la ricetta homebrew non
prevedeva il supporto per libstemmer (vedremo dopo a cosa serve),
quindi ho modificato leggermente la ricetta in questo modo (sudo brew
edit sphinx):
1 require 'formula'
2
3 class Sphinx < Formula
4 url 'http://sphinxsearch.com/downloads/sphinx-0.9.9.tar.gz'
5 homepage 'http://www.sphinxsearch.com'
6 md5 '7b9b618cb9b378f949bb1b91ddcc4f54'
7 head 'http://sphinxsearch.googlecode.com/svn/trunk/'
8
9 fails_with_llvm "fails with: ld: rel32 out of range in _GetPrivateProfileString from /usr/lib/libodbc.a(SQLGetPrivateProfileString.o)"
10
11 def install
12 system "curl -O http://snowball.tartarus.org/dist/libstemmer_c.tgz"
13 system "tar zxvf libstemmer_c.tgz"
14
15 args = ["--prefix=#{prefix}", "--disable-debug", "--disable-dependency-tracking", "--with-libstemmer"]
16 # configure script won't auto-select PostgreSQL
17 args << "--with-pgsql" if `/usr/bin/which pg_config`.size > 0
18 args << "--without-mysql" if `/usr/bin/which mysql`.size <= 0
19
20 system "./configure", *args
21 system "make install"
22 end
23
24 def caveats
25 <<-EOS.undent
26 Sphinx depends on either MySQL or PostreSQL as a datasource.
27
28 You can install these with Homebrew with:
29 brew install mysql
30 For MySQL server.
31
32 brew install mysql-connector-c
33 For MySQL client libraries only.
34
35 brew install postgresql
36 For PostgreSQL server.
37
38 We don't install these for you when you install this formula, as
39 we don't know which datasource you intend to use.
40 EOS
41 end
42 end
Configurazione
A questo punto, il peggio è passato. Thinking Sphinx è una gemma ottimamente documentata e seguita dal suo sviluppatore, e ti permette di impostare degli indici di ricerca per i tuoi modelli Rails direttamente al loro interno, grazie ad un semplice DSL di questo tipo:
1 class User < ActiveRecord::Base
2 devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
3
4 define_index do
5 indexes first_name
6 indexes last_name, :sortable => true
7 indexes email
8 indexes company
9 indexes company_role
10 indexes city
11 indexes website
12 indexes notes
13 set_property :enable_star => true
14 set_property :min_infix_len => 1
15 end
16
17 end
Avviare Sphinx
Una volta impostati gli indici (per maggiori info su come funziona
Sphinx rifatevi a questa
pagina, per
esempio), basta semplicemente far partire un rake task per convertire il
DSL in file di configurazione Sphinx: thinking_sphinx:configure.
Potete poi far partire il server Sphinx con thinking_sphinx:start.
Giuro che è stato veramente così semplice.
Thinking Sphinx dispone di una serie di rake task aggiuntivi per coprire tutti i vostri bisogni:
rake thinking_sphinx:configure # Generate the Sphinx configuration file using Thinking Sphinx's settings rake thinking_sphinx:index # Index data for Sphinx using Thinking Sphinx's settings rake thinking_sphinx:rebuild # Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx rake thinking_sphinx:reindex # Reindex Sphinx without regenerating the configuration file rake thinking_sphinx:restart # Restart Sphinx rake thinking_sphinx:running_start # Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings rake thinking_sphinx:start # Start a Sphinx searchd daemon using Thinking Sphinx's settings rake thinking_sphinx:stop # Stop Sphinx using Thinking Sphinx's settings rake thinking_sphinx:version # Output the current Thinking Sphinx version
Per ricercare facendo uso di Sphinx, rifatevi all'ottima guida, ma fondamentalmente si parla di fare cose come:
1 User.search(params[:search], :star => true, :order => :last_name).page(params[:page]).per(10)
E come forse vi state chiedendo sì, è già compatibile con
will_paginate e Kaminari (dalla versione ~> 2.0.3).
Word stemming
Se avete installato Sphinx con il flag --with-libstemmer da me suggerito qualche riga più in alto, allora avrete anche la possibilità di configurare il word stemming italiano. Questo significa che Sphinx sarà in grado di gestire correttamente le forme singolari/plurali delle ricerche, fornendo risultati più rilevanti.
Conclusioni
Quello che abbiamo visto è la base. Sphinx è incredibilmente potente e permette, ad esempio:
- La ricerca anche sulle relazioni delle entità;
- Ordinare i risultati per peso raggruppandoli in slot temporali (utile per ricerche real-time);
- Ricercare mediante più sintassi (da quella per operatori logici, a quella con wildcards);
- Effettuare ricerche geospaziali;
L'unico svantaggio di Sphinx rispetto ad altri motori di ricerca full-text è che gli indici devono essere totalmente rigenerati quando anche solo un'elemento della tabella cambia. In realtà anche questo aspetto è stato pressochè risolto mediante delta indexes, praticamente trasparenti all'utente.
Insomma. Sphinx mi ha convinto.