Přejít k navigační liště

Zdroják » Databáze » Konfigurace Sphinx Search

Konfigurace Sphinx Search

Články Databáze

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.

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í.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.