Konfigurace Sphinx Search

Tentokrát si ukážeme, jak vypadá základní konfigurace Sphinx Search a co je vše potřeba udělat, abychom nějaká data zaindexovali a mohli v nich vyhledávat.
Seriál: Úvod do Sphinx Search (4 díly)
- Úvod do Sphinx Search 27. 5. 2013
- Konfigurace Sphinx Search 10. 6. 2013
- Sphinx Search API 24. 6. 2013
Nálepky:
Instalace
I když v linuxových distribucích už Sphinx Search obvykle je (v Ubuntu celkem aktuální, v Debianu dost stará verze), doporučuji si stáhnout aktuální verzi přímo od Sphinx. V závislosti na operačním systému pak najděte konfigurační soubor sphinx.conf
(v Linuxu obvykle /etc/sphinxsearch/sphinx.conf
).
Konfigurace
Konfigurační soubor pro Sphinx sestává z několika částí: indexer
, searchd
, source
a index
. Zdrojů dat (source) a indexů může být libovolný počet.
Součástí Sphinx Search je ukázkový konfigurační soubor, ze kterého můžete vyjít. Ale obsahuje mnoho zakomentovaných direktiv, které vás sice mohou nasměrovat, ale zároveň i zmást, protože ve většině případů vyhovují výchozí hodnoty, a nastavovat je nemusíte.
Já začnu naopak prázdným textovým souborem sphinx.conf
a vytvořím úplně minimalistickou konfiguraci. Její jednotlivé části by mohly vypadat takto:
indexer a searchd
Část indexer
obsahuje konfiguraci indexování dat. Tato nastavení mohou ovlivnit rychlost indexace, ale nikoliv rychlost vyhledávání. Část searchd
konfiguruje vyhledávacího démona, který běží na pozadí a ta naopak ovlivňuje vyhledávání.
indexer
{
mem_limit = 256M
}
searchd
{
listen = 9312
pid_file = /var/run/sphinxsearch/searchd.pid
log = /var/log/sphinxsearch/searchd.log
query_log = /var/log/sphinxsearch/query.log
}
Indexeru jsem zvýšil pouze memory limit. Výchozí je 32M a indexer by si s ním vystačil, ale takhle bude rychlejší. Kdysi jsem si dělal měření rychlosti indexace v závislosti na limitu paměti a od 128 MB výš, už jsem nepozoroval žádné zlepšení. Samozřejmě vždy závisí na konkrétních datech, takže doporučuji vyzkoušet třeba 128/256/512M a uvidíte.
pid_file
je povinná položka definující cestu k PID (process ID) souboru. Tam searchd ukládá číslo svého procesu. A pak jsou tam dva logy (log démona searchd a log dotazů).
Pomocí listen
definujete, jak budete searchd
pak komunikovat. Může to být host:port:protocol nebo unixový socket (/cesta/k/souboru/sphinx.s). Položek listen
může být víc, searchd
tak může poslouchat na několika portech nebo socketech. Toho se často využívá, když chcete používat jak SphinxApi (port 9312), tak SphinxQL (localhost:9306:mysql41).
Indexy a zdroje dat
Aby byl searchd
vůbec spustitelný, musíme nadefinovat alespoň jeden zdroj dat source
a alespoň jeden index
.
Zdroje dat
Řekněme, že máme jednoduchou databázovou tabulku v MySQL, s následující strukturou. Jsou to nějaké univerzální položky, třeba si je představme jako články:
id int(11) unsigned datetime datetime title varchar(255) body text
Nejjednodušší definice zdroje dat by mohla vypadat takto:
source mysource
{
type = mysql
sql_host = localhost
sql_user = uzivatel
sql_pass = heslo
sql_db = databaze
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = \
SELECT id, title, body, UNIX_TIMESTAMP(datetime) datetime \
FROM items
sql_attr_timestamp = datetime
}
Na začátku se připojíme k databázi. Poté se vykonají SQL dotazy sql_query_pre
, kterých může být i víc. Tady to například využívám k nastavení kódování znaků. Obdobně lze nakonec použít sql_query_post
nebo sql_query_post_index
.
Nejdůležitější je ale položka sql_query
, která obsahuje samotný SELECT dat pro indexaci. Vždy musí začínat unikátním ID typu int unsigned
. Všechny následující textové sloupce budou indexovány jako fulltextové položky, pokud dále neuvedete jinak.
Kromě textových položek umí Sphinx indexovat tzv. atributy. Ty nejsou indexovány fulltextově, ale lze podle nich filtrovat a třídit. Jsou to:
- integer
- timestamp
- float
- string ordinal (převedený na ineteger)
- string
- JSON
- multi-value integer
Například sloupec datetime
není textový, tak ho pomocí sql_attr_timestamp = datetime
nadeklarujeme jako atribut typu timestamp.
Podle zbylých fulltextových položek title
a body
bude možné vyhledávat, ale Sphinx je nebude ukládat a tudíž ani vracet jejich hodnotu. Pokud bychom položku nadeklarovali jako atribut typu string (např. sql_attr_string = title
), bude ji Sphinx ukládat a vracet, ale zase v ní nebude fulltextově vyhledávat. Proto u textových položek existuje ještě možnost nadeklarovat položku jako field (sql_field_string = title
). Potom ji bude Sphinx vracet i hledat v ní.
Indexy
Konfigurace indexů určuje, jakým způsobem budou data indexována.
index myindex
{
source = mysource
path = /var/lib/sphinxsearch/data/myindex
enable_star = 1
min_prefix_len = 3
charset_type = utf-8
charset_table = 0..9, A..Z->a..z, _, a..z, U+0e1->a, U+0c1->a, U+10d->c, U+10c->c, U+10f->d, U+10e->d, U+0e9->e, U+0c9->e, U+11b->e, U+11a->e, U+0ed->i, U+0cd->i, U+148->n, U+147->n, U+0f3->o, U+0d3->o, U+159->r, U+158->r, U+161->s, U+160->s, U+165->t, U+164->t, U+0fa->u, U+0da->u, U+16f->u, U+16e->u, U+0fd->y, U+0dd->y, U+17e->z, U+17d->z,
}
Na začátku definujeme, jaký zdroj dat source
se má indexovat a kde na disku path
bude soubor s indexem. Ono to ve skutečnosti bude devět souborů s tímto názvem, ale různými koncovkami.
enable_star = 1
zapne možnost používat při hledání rozšíření pomocí hvězdičky (např. slovo*). Minimální délku základu pro pravostranné rozšíření definuje min_prefix_len
. Pomocí min_infix_len
by šlo povolit i levostranné rozšíření, ale moc se to nepoužívá a také by byl index dvojnásobně velký, protože by všechna slova byla indexována zleva i zprava.
Nastavit charset_type = utf-8
je důležité, protože default je SBCS
(Single Byte Character Set).
charset_table
má dvojí funkci. 1) definuje znaky, které mají být považovány za písmena tvořící slova. Ostatní znaky budou brány jako oddělovače slov. 2) umožňuje transformaci těchto znaků na jiné. Například A..Z->a..z
převádí velká písmena na malá. A ta šílenost za tím ořezává diakritiku u českých znaků a rovněž je převádí na malá písmena (např. U+0e1->a
převede á->a
). Tato ukázka zahrnuje jen češtinu, patrně si tam budete chtít podle požadovaného jazyka doplnit další transformace.
Převod znaků pomocí charset_table
se provádí jednak při indexaci a za druhé před položením dotazu.
Zkouška vyhledávání
Pokud máme vše nastaveno, pustíme poprvé indexer.
indexer myindex
Pokud vše proběhlo správně, můžeme vyzkoušet hledání pomocí příkazu search
. Ten je zajímavý tím, že pracuje přímo s indexy a ke své funkci nepotřebuje běžící searchd
. Hodí se proto na prvotní otestování zaindexovaných dat.
search -i myindex "dotaz"
Pozn. Pokud při indexaci již běží demon searchd
, nenechá vás sahat na index, který používá. Protože vypnout searchd
na indexaci většinou nepřipadá v úvahu, lze použít rotaci indexu, kterou lze udělat za běhu.
indexer --rotate myindex
Rotaci lze ale provést jen na indexu, který již existoval v době startu searchd
. Po vytvoření nového indexu je tedy vhodné searchd
restartovat.
searchd --stop searchd
Závěr
Příště si ukážeme, jak pokládat dotazy Sphinxu z vlastní aplikace, selekční jazyk a vůbec jaké jsou možnosti vyhledávání a třídění.