Abilitare SphinxSE in MariaDB

A partire da MariaDB 5.2.2, lo Storage Engine Sphinx è incluso nei sorgenti, nei binari e nei pacchetti di MariaDB. SphinxSE è compilato come plugin .so caricabile dinamicamente. Per utilizzarlo occorre eseguire un'unica volta: INSTALL PLUGIN:

MariaDB [(none)]> INSTALL PLUGIN sphinx SONAME 'ha_sphinx.so';
Query OK, 0 rows affected (0.00 sec)

Una volta installato, SphinxSE apparirà nell'elenco degli Storage Engine installati:

MariaDB [(none)]> show engines;
+------------+---------+--------------------------------------------+--------------+------+------------+
| Engine     | Support | Comment                                    | Transactions | XA   | Savepoints |
+------------+---------+--------------------------------------------+--------------+------+------------+
...
| SPHINX     | YES     | Sphinx storage engine 0.9.9                | NO           | NO   | NO         |
...
+------------+---------+--------------------------------------------+--------------+------+------------+

Questo deve essere fatto una sola volta.

Nota: SphinxSE è solo la parte di Sphinx che funge da Storage Engine. Per poterlo utilizzare in MariaDB, occorre installare Sphinx.

A dispetto del suo nome, SphinxSE di per sé non gestisce i dati. In effetti non è altro che un client built-in che permette a MariaDB di comunicare con searchd, eseguire ricerche e ottenere i risultati. Tutta la parte di indicizzazione e di ricerca avviene fuori da MariaDB.

Ecco alcune applicazioni di SphinxSE:

  • port più semplice delle applicazioni FTS MariaDB/MySQL a Sphinx
  • permettere l'uso di Sphinx con linguaggi di programmazione che non dispongono ancora delle API necessarie
  • ottimizzazioni che riguardano l'elaborazione del set dei risultati di Sphinx dal lato di MariaDB (esempi; JOIN con la tabella dei documenti originali, ulteriori filtri operati da MariaDB, etc...)

Usare SphinxSE

Utilizzo di base

Per effettuare ricerche con SphinxSE, occorre creare una particolare "tabella di ricerca" ENGINE=SPHINX, ed effettuare una SELECT su di essa, con la query full text nella clausola WHERE.

Ecco un esempio di istruzione CREATE e di query per la ricerca:

CREATE TABLE t1
(
    id          INTEGER UNSIGNED NOT NULL,
    weight      INTEGER NOT NULL,
    query       VARCHAR(3072) NOT NULL,
    group_id    INTEGER,
    INDEX(query)
) ENGINE=SPHINX CONNECTION="sphinx://localhost:9312/test";

SELECT * FROM t1 WHERE query='test it;mode=any';

Le prime tre colonne della tabella devono essere dei seguenti tipi: INTEGER UNSINGED o BIGINT per la prima colonna (id del documento), INTEGER o BIGINT per la seconda colonna ("peso" della corrispondenza) e VARCHAR o TEXT per la terza colonna (la query). Queste associazioni sono fisse; non si può omettere una di queste tre colonne, modificare la loro posizione o cambiare i tipi. Inoltre la colonna query deve essere indicizzata; tutte le altre devono essere mantenute senza indici. I nomi delle colonne vengono ignorati, perciò è possibile sceglierli arbitrariamente.

Le colonne aggiuntive possono essere INTEGER, TIMESTAMP, BIGINT, VARCHAR o FLOAT. Saranno legate agli attributi forniti nel set di risultati forniti da Sphinx in base al loro nome, perciò i loro nomi devono corrispondere ai nomi degli attributi specificati in sphinx.conf. Se nei risultati non sono presenti nomi di attributi, le colonne aggiuntive avranno valori NULL.

Alcuni particolari nomi di attributi "virtuali" possono essere associati alle colonne SphinxSE. _sph_ deve essere usato al posto di @. Per esempio, per ottenere i valori degli attributi virtuali '@groupby', '@count' o '@distinct', si usano rispettivamente i nomi di colonna '_sph_groupby', '_sph_count' o '_sph_distinct'.

Il parametro stringa CONNECTION serve a specificare l'host searchd predefinito, la porta e gli indici per le query lanciate sulla tabella. Se non viene fornita alcune stringa di connessione nella CREATE TABLE, saranno usati il nome di indice '*' (cioè tutti gli indici) e 'localhost:9312'. La sintassi della stringa di connessione è la seguente:

CONNECTION="sphinx://HOST:PORTA/NOMEINDICE"

E' possibile modificare successivamente la stringa di connessione predefinita, in questo modo:

ALTER TABLE t1 CONNECTION="sphinx://NUOVO_HOST:NUOVA_PORTA/NUOVO_NOMEINDICE";

E' anche possibile per le singole query scavalcare questi parametri.

Opzioni di ricerca

Come visto nell'esempio sopra, il testo delle query e le opzioni di ricerca dovrebbero essere inseriti nella clausola 'WHERE' nella colonna delle query (cioè la terza colonna); le opzioni sono separate da punti e virgola (';') e i nomi devono essere separati dai valori tramite il segno uguale ('='). E' possibile specificare un qualsiasi numero di opzioni. Le opzioni disponibili sono:

  • query - il testo della query;
  • mode - modalità di corrispondenza. Può essere: "all", "any", "phrase", "boolean" o "extended". Il predefinito è "all";
  • sort - modalità di orginamento. Può essere "relevance", "attr_desc", "attr_asc", "time_segments" o "extended". In tutte le modalità, eccetto "relevance", deve essere specificato il nome dell'attributo (o la clausola di ordinamento, nel caso di "extended") dopo un segno di due punti:
... WHERE query='test;sort=attr_asc:group_id';
... WHERE query='test;sort=extended:@weight desc, group_id asc';
  • offset - offset nel set dei risultati, il default è 0;
  • limit - il numero di righe da estrarre dai risultati, il default è 20;
  • index - i nomi degli indici da cercare:
... WHERE query='test;index=test1;';
... WHERE query='test;index=test1,test2,test3;';
  • minid, maxid - ID del documento minimo e massimo;
  • weights - elenco dei pesi, separato da virgole, da assegnare ai campi full-text di Sphinx:
... WHERE query='test;weights=1,2,3;';
  • filter, !filter - nomi di attributi separati da virgole e i valori associati:
# include solo i gruppi 1, 5 e 19
... WHERE query='test;filter=group_id,1,5,19;';

# esclude i gruppi 3 e 11
... WHERE query='test;!filter=group_id,3,11;';
  • range, !range - nomi di attributi separati da virgole, valori minimi e massimi:
# include i gruppi da 3 a 7 compresi
... WHERE query='test;range=group_id,3,7;';

# esclude i gruppi da 5 a 25
... WHERE query='test;!range=group_id,5,25;';
  • maxmatches - valori delle corrispondenza per ogni query:
... WHERE query='test;maxmatches=2000;';
  • groupby - funzione e attributo group-by:
... WHERE query='test;groupby=day:published_ts;';
... WHERE query='test;groupby=attr:group_id;';
  • groupsort - clausola di ordinamento group-by:
... WHERE query='test;groupsort=@count desc;';
  • indexweights - elenco separato da virgole dei nomi degli indici e dei pesi da usare nel cercare nei diversi indici:
... WHERE query='test;indexweights=idx_exact,2,idx_stemmed,1;';
  • comment - una stringa da associare a questa query nel log delle query (associata al parametro $comment nella chiamata a Query()):
... WHERE query='test;comment=marker001;';
  • select - una stringa con le espressioni da calcolare (associate alla chiamata a SetSelect()):
... WHERE query='test;select=2*a+3*b as myexpr;';

Nota: E' molto più efficiente permettere a Sphinx di effettuare l'ordinamento, il filtraggio e la riduzione dei risultati, piuttosto che ottenere il massimo dei risultati e utilizzare le clausole 'WHERE', 'ORDER BY' e 'LIMIT' dal lato di MariaDB. Questo per due motivi:

  1. Sphinx effettua un certo numero di ottimizzazioni, e in questo genere di operazioni si comporta meglio di MariaDB/MySQL.
  2. Una minor quantità di dati dovrà essere compressa da searchd, e trasferita e decompressa da SphinxSE.

SHOW ENGINE SPHINX STATUS

A partire dalla versione 0.9.9-rc1, alcune informazioni aggiuntive sulle query possono essere lette con l'istruzione 'SHOW ENGINE SPHINX STATUS':

mysql> SHOW ENGINE SPHINX STATUS;
+--------+-------+-------------------------------------------------+
| Type   | Name  | Status                                          |
+--------+-------+-------------------------------------------------+
| SPHINX | stats | total: 25, total found: 25, time: 126, words: 2 | 
| SPHINX | words | sphinx:591:1256 soft:11076:15945                | 
+--------+-------+-------------------------------------------------+
2 rows in set (0.00 sec)

E' anche possibile accedere a queste informazioni tramite le variabili di stato. Si noti che questo metodo non richiede il privilegio super user.

mysql> SHOW STATUS LIKE 'sphinx_%';
+--------------------+----------------------------------+
| Variable_name      | Value                            |
+--------------------+----------------------------------+
| sphinx_total       | 25                               | 
| sphinx_total_found | 25                               | 
| sphinx_time        | 126                              | 
| sphinx_word_count  | 2                                | 
| sphinx_words       | sphinx:591:1256 soft:11076:15945 | 
+--------------------+----------------------------------+
5 rows in set (0.00 sec)

Le JOIN con SphinxSE

E' possibile effettuare delle JOIN su una tabella di ricerca SphinxSE e altre tabelle che utilizzano Storage Engine differenti. Ecco un esempio con i "documenti" di example.sql:

mysql> SELECT content, date_added FROM test.documents docs
-> JOIN t1 ON (docs.id=t1.id) 
-> WHERE query="one document;mode=any";
+-------------------------------------+---------------------+
| content                             | docdate             |
+-------------------------------------+---------------------+
| this is my test document number two | 2006-06-17 14:04:28 | 
| this is my test document number one | 2006-06-17 14:04:28 | 
+-------------------------------------+---------------------+
2 rows in set (0.00 sec)

mysql> SHOW ENGINE SPHINX STATUS;
+--------+-------+---------------------------------------------+
| Type   | Name  | Status                                      |
+--------+-------+---------------------------------------------+
| SPHINX | stats | total: 2, total found: 2, time: 0, words: 2 | 
| SPHINX | words | one:1:2 document:2:2                        | 
+--------+-------+---------------------------------------------+
2 rows in set (0.00 sec)

Creare degli snippet (estratti) con MariaDB

A partire dalla versione 0.9.9-rc2, SphinxSE comprende una funzione UDF che permette di creare degli snippet attraverso MariaDB. Questa funzionalità è molto simile alla funzione API BuildExcerprts, che è accessibile tramite MariaDB+SphinxSE.

Il binario che contiene la UDF si chiama sphinx.so e viene creato e installato automaticamente nel percorso corretto insieme a SphinxSE. Per registrare la UDF si esegua la seguente istruzione:

CREATE FUNCTION sphinx_snippets RETURNS STRING SONAME 'sphinx.so';

Il nome della funzione deve essere 'sphinx_snippets', non è possibile usarne uno arbitrario. Gli argomenti sono i seguenti:

Prototype: function sphinx_snippets ( documento, indice, parole, [opzioni] );

Gli argomenti documento e parole possono essere stringhe o colonne di una tabella. Le opzioni devono essere specificate in questo modo: <code>'valore' AS nome_opzione</code>. L'elenco delle opzioni supportate è disponibile nella documentazione della funzione API BuildExcerprts(). L'unica opzione specifica dell'UDF è 'sphinx', che permette di specificare dove si trova searchd (host e porta).

Esempi d'uso:

SELECT sphinx_snippets('hello world doc', 'main', 'world',
    'sphinx://192.168.1.1/' AS sphinx, true AS exact_phrase,
    '[b]' AS before_match, '[/b]' AS after_match)
FROM documents;

SELECT title, sphinx_snippets(text, 'index', 'mysql php') AS text
    FROM sphinx, documents
    WHERE query='mysql php' AND sphinx.id=documents.id;

Versioni di Sphinx utilizzate

Ulteriori informazioni

Ulteriori informazioni su Sphinx e SphinxSE sono disponibili sul sito di Sphinx.

Commenti

Sto caricando i commenti......
Loading