Sphinx: Różnice pomiędzy wersjami
Linia 11: | Linia 11: | ||
* <code>indextool</code> - program narzędziowy do zrzucania rozmaitych; | * <code>indextool</code> - program narzędziowy do zrzucania rozmaitych; | ||
* <code>wordbreaker</code> - program służący do rozdzielania połączonych wyrazów na oddzielne. | * <code>wordbreaker</code> - program służący do rozdzielania połączonych wyrazów na oddzielne. | ||
+ | |||
+ | === Przykład === | ||
+ | |||
+ | Poniżej znajduje się przykład indeksowania wiadomości. | ||
+ | |||
+ | ==== Konfiguracja cz. 1==== | ||
+ | |||
+ | Dla wygodniejszej pracy zalecane jest stworzenie paru katalogów, na przykład: | ||
+ | * <code class="directory">wyszukiwanie/dane/wiadomosci</code> - wszystkie artykuły; | ||
+ | * <code class="directory">wyszukiwanie/index/wiadomosci</code> - wszystkie pliki stworze podczas indeksowania; | ||
+ | * <code class="directory">wyszukiwanie/conf</code> - pliki konfiguracyjne; | ||
+ | * <code class="directory">wyszukiwanie/bin/wiadomosci</code> - skrypty potrzebne do indeksowania. | ||
+ | |||
+ | Plik konfiguracyjny <code class="directory">wyszukiwanie/conf/sphinx.conf</code>: | ||
+ | <syntaxhighlight lang="text"> | ||
+ | source wiadomosci | ||
+ | { | ||
+ | type = xmlpipe | ||
+ | xmlpipe_command = ~/wyszukiwanie/bin/wiadomosci/xmlout.sh | ||
+ | xmlpipe_field = content | ||
+ | xmlpipe_attr_string = url | ||
+ | xmlpipe_attr_uint = date | ||
+ | xmlpipe_fixup_utf8 = 1s | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * <code>source wiadomosci</code> - definicja źródła indeksowania identyfikowana jako ''wiadomosci''. | ||
+ | * <code>type = xmlpipe</code> - definicja typu źródła indeksowania, tutaj to dokument XML, który jest przekazywany za pomocą pipe do indexera. | ||
+ | * <code>xmlpipe_command = ~/wyszukiwanie/bin/news/xmlout.sh</code> - jest to komenda, która zostanie uruchomiana aby wypisała na standardowe wyjście wszystkie dokumenty XML jako jeden dokument. | ||
+ | |||
+ | ==== Pola i atrybuty ==== | ||
+ | |||
+ | Zawartość dokumentu, która potrzebuje być zindeksowana nazywana jest polem (field). Intuicyjnie dla wiadomości (newsów) cała treść artykułu jest polem. | ||
+ | |||
+ | Atrybut jest informacją powiązaną z artykułu. | ||
+ | |||
+ | Gdy jedno z wyszukiwań dopasuje szukane frazy do fraz zindexowanych we wszystkich dokumentach to dla każdego dopasowanego artykułu zwracany jest sam dokument wraz z jego atrybutami. | ||
+ | |||
+ | <syntaxhighlight lang="text"> | ||
+ | xmlpipe_field = content | ||
+ | xmlpipe_attr_string = url | ||
+ | xmlpipe_attr_uint = date | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Powyższa zawartość określa: | ||
+ | * Tekst w tagu XML ''content'' będzie traktowany jako pole (field), więc będzie indeksowane | ||
+ | * Tekst w tagu XML ''url'' będzie traktowany jak atrybut tekstowy (string). | ||
+ | * Tekst w tagu XML ''date'' będzie traktowany jak atrybut numeryczny (numerical). | ||
+ | |||
+ | Numeryczny atrybut daty wydaje się nieintuicyjny. Natomiast podczas szukania można zdefiniować nie tylko konkretne wartości atrybutów, ale i ich zakresy, które nie działają najlepiej z atrybutem tekstowym. | ||
+ | |||
+ | <syntaxhighlight lang="text"> | ||
+ | xmlpipe_fixup_utf8 = 1 | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Powyższa linijka sprawi, że indexer da sobie radę ze streamem XML w UTF-8. | ||
+ | |||
+ | ==== XML ==== | ||
+ | |||
+ | Poniżej są 2 przykładowe artykuły z następującą treścią: | ||
+ | |||
+ | <syntaxhighlight lang="text"> | ||
+ | Gmina Ostrowice w Zachodniopomorskiem może zostać zlikwidowana za długi. Jej zadłużenie trzykrotnie przewyższa roczne dochody. | ||
+ | </syntaxhighlight> | ||
+ | i | ||
+ | <syntaxhighlight lang="text"> | ||
+ | Miasto Słupsk popadło w kłopoty finansowe, po przegranym procesie, który miastu wytoczył wyrzucony z budowy słupskiego aquaparku wykonawca. Miasto ma zapłacić firmie Termochem 24 miliony złotych. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Indexer będzie się spodziewał takiego streamu: | ||
+ | |||
+ | <syntaxhighlight lang="xml"> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <sphinx:docset> | ||
+ | <sphinx:document id="1"> | ||
+ | <url>url</url> | ||
+ | <date>data</date> | ||
+ | <content>Gmina Ostrowice w Zachodniopomorskiem może zostać zlikwidowana za długi. Jej zadłużenie trzykrotnie przewyższa roczne dochody.</content> | ||
+ | </sphinx:document> | ||
+ | <sphinx:document id="2"> | ||
+ | <url>url</url> | ||
+ | <date>data</date> | ||
+ | <content>Miasto Słupsk popadło w kłopoty finansowe, po przegranym procesie, który miastu wytoczył wyrzucony z budowy słupskiego aquaparku wykonawca. Miasto ma zapłacić firmie Termochem 24 miliony złotych.</content> | ||
+ | </sphinx:document> | ||
+ | </sphinx:docset> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Rzeczy warte zauważenia: | ||
+ | * każdy dokument musi mieć numeryczne id, | ||
+ | * wszystkie tagi niezaczynające się od sphinx: zostały zdefiniowane w pliku konfiguracyjnym. | ||
+ | |||
+ | Kolejnym etapem jest stworzenie skryptu <code class="directory">~/wyszukiwanie/bin/wiadomosci/xmlout.sh</code>, który wygeneruje powyższy XML. Poniżej znajduje się przykładowy: | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | #!/bin/bash | ||
+ | echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" | ||
+ | echo "<sphinx:docset>" | ||
+ | counter=0 | ||
+ | for filename in `find ~/wyszukiwanie/dane/wiadomosci/ -type f` | ||
+ | do | ||
+ | url=`head -n 2 $filename | tail -n 1` | ||
+ | url=`echo $url | sed 's/&/%26/g' ` | ||
+ | date=`head -n 1 $filename | sed 's/\-//g'` | ||
+ | counter=`expr $counter + 1` | ||
+ | lines=`wc -l $filename | awk '{print $1}'` | ||
+ | lines=`expr $lines - 2` | ||
+ | echo "<sphinx:document id=\"$counter\">" | ||
+ | echo "<url>$url</url>" | ||
+ | echo "<date>$date</date>" | ||
+ | echo -n "<content>" | ||
+ | tail -n $lines $filename | sed 's/&/and/g' | ||
+ | echo "</content>" | ||
+ | echo "</sphinx:document>" | ||
+ | done | ||
+ | echo "</sphinx:docset>" | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== Konfiguracja cz. 2 ==== | ||
+ | |||
+ | Druga część konfiguracji odpowiada za indexera: | ||
+ | |||
+ | <syntaxhighlight lang="text"> | ||
+ | index wiadomosci | ||
+ | { | ||
+ | source = wiadomosci | ||
+ | path = ~/wyszukiwanie/index/wiadomosci/idx | ||
+ | docinfo = extern | ||
+ | mlock = 0 | ||
+ | morphology = stem_en, soundex | ||
+ | min_word_len = 1 | ||
+ | charset_type = utf-8 | ||
+ | html_strip = 1 | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
=== Odnośniki Zewnętrzne === | === Odnośniki Zewnętrzne === | ||
* [http://sphinxsearch.com/ Sphinx Search] | * [http://sphinxsearch.com/ Sphinx Search] | ||
− | |||
[[Kategoria:Bazy danych]] | [[Kategoria:Bazy danych]] |
Wersja z 13:25, 25 lip 2015
Sphinx to otwarty, w pełni tekstowy serwer wyszukiwania stworzony w C++ i udostępniony na licencji GPLv2. Najczęściej jest wykorzystywany do indeksowania danych z baz MySQL, PostreSQL i specjalnie sformatowanych plików xml.
Spis treści
Elementy Sphinxa
Sphinx składa się z następujących elementów:
-
indexer
- narzędzie do tworzenia pełnotekstowych indeksów (indices); -
searchd
- demon do przeszukiwania indeksów przez zewnętrzne aplikacji (np. skrypty www komunikujące się przez API, MySQ z SphinxSE itp.), jest uruchomiony na serwerze; -
sphinxapi
- zbiór bibliotek udostępniających API Sphinxa dla PHP, Pythona, Javy, Perla, czy Rubiego; -
spelldump
- proste narzędzie do wydobywania pozycji ze słownika ispell lub MySpell służące do dostosowania indexu; -
indextool
- program narzędziowy do zrzucania rozmaitych; -
wordbreaker
- program służący do rozdzielania połączonych wyrazów na oddzielne.
Przykład
Poniżej znajduje się przykład indeksowania wiadomości.
Konfiguracja cz. 1
Dla wygodniejszej pracy zalecane jest stworzenie paru katalogów, na przykład:
-
wyszukiwanie/dane/wiadomosci
- wszystkie artykuły; -
wyszukiwanie/index/wiadomosci
- wszystkie pliki stworze podczas indeksowania; -
wyszukiwanie/conf
- pliki konfiguracyjne; -
wyszukiwanie/bin/wiadomosci
- skrypty potrzebne do indeksowania.
Plik konfiguracyjny wyszukiwanie/conf/sphinx.conf
:
source wiadomosci { type = xmlpipe xmlpipe_command = ~/wyszukiwanie/bin/wiadomosci/xmlout.sh xmlpipe_field = content xmlpipe_attr_string = url xmlpipe_attr_uint = date xmlpipe_fixup_utf8 = 1s }
-
source wiadomosci
- definicja źródła indeksowania identyfikowana jako wiadomosci. -
type = xmlpipe
- definicja typu źródła indeksowania, tutaj to dokument XML, który jest przekazywany za pomocą pipe do indexera. -
xmlpipe_command = ~/wyszukiwanie/bin/news/xmlout.sh
- jest to komenda, która zostanie uruchomiana aby wypisała na standardowe wyjście wszystkie dokumenty XML jako jeden dokument.
Pola i atrybuty
Zawartość dokumentu, która potrzebuje być zindeksowana nazywana jest polem (field). Intuicyjnie dla wiadomości (newsów) cała treść artykułu jest polem.
Atrybut jest informacją powiązaną z artykułu.
Gdy jedno z wyszukiwań dopasuje szukane frazy do fraz zindexowanych we wszystkich dokumentach to dla każdego dopasowanego artykułu zwracany jest sam dokument wraz z jego atrybutami.
xmlpipe_field = content xmlpipe_attr_string = url xmlpipe_attr_uint = date
Powyższa zawartość określa:
- Tekst w tagu XML content będzie traktowany jako pole (field), więc będzie indeksowane
- Tekst w tagu XML url będzie traktowany jak atrybut tekstowy (string).
- Tekst w tagu XML date będzie traktowany jak atrybut numeryczny (numerical).
Numeryczny atrybut daty wydaje się nieintuicyjny. Natomiast podczas szukania można zdefiniować nie tylko konkretne wartości atrybutów, ale i ich zakresy, które nie działają najlepiej z atrybutem tekstowym.
xmlpipe_fixup_utf8 = 1
Powyższa linijka sprawi, że indexer da sobie radę ze streamem XML w UTF-8.
XML
Poniżej są 2 przykładowe artykuły z następującą treścią:
Gmina Ostrowice w Zachodniopomorskiem może zostać zlikwidowana za długi. Jej zadłużenie trzykrotnie przewyższa roczne dochody.
i
Miasto Słupsk popadło w kłopoty finansowe, po przegranym procesie, który miastu wytoczył wyrzucony z budowy słupskiego aquaparku wykonawca. Miasto ma zapłacić firmie Termochem 24 miliony złotych.
Indexer będzie się spodziewał takiego streamu:
<?xml version="1.0" encoding="utf-8"?> <sphinx:docset> <sphinx:document id="1"> <url>url</url> <date>data</date> <content>Gmina Ostrowice w Zachodniopomorskiem może zostać zlikwidowana za długi. Jej zadłużenie trzykrotnie przewyższa roczne dochody.</content> </sphinx:document> <sphinx:document id="2"> <url>url</url> <date>data</date> <content>Miasto Słupsk popadło w kłopoty finansowe, po przegranym procesie, który miastu wytoczył wyrzucony z budowy słupskiego aquaparku wykonawca. Miasto ma zapłacić firmie Termochem 24 miliony złotych.</content> </sphinx:document> </sphinx:docset>
Rzeczy warte zauważenia:
- każdy dokument musi mieć numeryczne id,
- wszystkie tagi niezaczynające się od sphinx: zostały zdefiniowane w pliku konfiguracyjnym.
Kolejnym etapem jest stworzenie skryptu ~/wyszukiwanie/bin/wiadomosci/xmlout.sh
, który wygeneruje powyższy XML. Poniżej znajduje się przykładowy:
#!/bin/bash echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" echo "<sphinx:docset>" counter=0 for filename in `find ~/wyszukiwanie/dane/wiadomosci/ -type f` do url=`head -n 2 $filename | tail -n 1` url=`echo $url | sed 's/&/%26/g' ` date=`head -n 1 $filename | sed 's/\-//g'` counter=`expr $counter + 1` lines=`wc -l $filename | awk '{print $1}'` lines=`expr $lines - 2` echo "<sphinx:document id=\"$counter\">" echo "<url>$url</url>" echo "<date>$date</date>" echo -n "<content>" tail -n $lines $filename | sed 's/&/and/g' echo "</content>" echo "</sphinx:document>" done echo "</sphinx:docset>"
Konfiguracja cz. 2
Druga część konfiguracji odpowiada za indexera:
index wiadomosci { source = wiadomosci path = ~/wyszukiwanie/index/wiadomosci/idx docinfo = extern mlock = 0 morphology = stem_en, soundex min_word_len = 1 charset_type = utf-8 html_strip = 1 }