sysops.it

Outsourcing IT pozwoli ci prowadzić biznes taniej

info@sysops.it
+48 666 930 111

Nowości z bloga

TCP Fast Open

Opis modyfikacji stosu TCP, która może przyspieszyć prędkość ładowania popularnych stron od 4% do 41%.

Wyszukiwarki i Sphinx

Słowo wstępu o Sphinksie - silniku wspierającym wyszukiwanie pełnotekstowe.

Kwestia IPv6 NAT w Linuksie

IPv6 NAT w Linuksie - walka ideologii z rzeczywistością.

Wyszukiwarki i Sphinx

Sphinx Search

Niniejszy wpis o wyszukiwarkach jest kontynuacją artykułu o indeksie pełnotekstowym MySQL-a.

Wstęp

Wraz z rozwojem programowania obiektowego coraz więcej uwagi zaczęto przykładać do odpowiedzialności. Sposób myślenia obiektowego o danym problemie narzuca konieczność podjęcia decyzji, za co będzie odpowiedzialny dany fragment aplikacji. Krańcowym przypadkiem jest ustalenie, że dana część aplikacji powinna być odpowiedzialna za jeden konkretny proces. I jest to poprawne podejście do odpowiedzialności. Mówimy w końcu o zasadzie spójności czy zasadzie pojedynczej odpowiedzialności.

W jaki sposób wiąże się to z zewnętrznym silnikiem wyszukiwania, którym jest Sphinx?

Wyłuskiwanie danych z baz

Bazy danych radzą sobie z przechowywaniem danych. Są odpowiedzialne za gromadzenie danych w uprzednio ustalonych strukturach. Odpowiedzialność baz danych sięga również do prezentacji, czyli przedstawienia (zwrócenia) danych na żądanie. Dopóki struktury bazy pozwalają na dostęp do danych, wszystko jest w porządku. Przykładowymi zapytaniami, które przewiduje sama struktura baz, są m.in. pobieranie danych z grudnia, wyświetlenie danych o ID równym 14 albo tych danych, gdzie pole o typie wyliczeniowym to słowo “disabled”.

Możemy zatem zauważyć, że to struktura bazy (timestamp, pole ID, pole ENUM) pozwala na filtrowanie danych wyłącznie przy użyciu silnika bazy danych.

Tego typu wyszukiwania można było uznać za wystarczające kilka lat temu. Serwisy społecznościowe, popularne sklepy, serwisy aukcyjne czy wreszcie wyszukiwarki internetowe z firmą Google na czele przyzwyczaiły nas do bardziej złożonych zapytań. O dane pytamy się inaczej. Chcemy wiedzieć też więcej od tego, jaką zawartość ma rekord z ID równym 14. W miarę potrzeb szukamy przecież wycieczek do Turcji, przepisów na bigos czy włoskich restauracji w centrum Radomia.

Odpowiedzialność baz za wyszukiwanie pełnotekstowe

Podobne potrzeby powinna spełniać wyszukiwarka na naszej stronie lub naszym sklepie internetowym. Jest to moment, w którym wracamy do odpowiedzialności baz danych. Czy baza danych jest odpowiedzialna za wyszukiwanie pełnotekstowe? Teoretycznie tak, może być odpowiedzialna.

Odpowiedzialność bazy danych jest pewnym uproszczeniem. Żadne dane nie są trzymane w bazie bezpośrednio. Dane gromadzone są w wierszach podzielonych na kolumny. Wszystkie wiersze zgrupowane są w jedną strukturę – tabelę. Poza tabelami dane można prezentować w postaci widoków. Dopiero widoki i tabele są częścią naszej bazy danych. Każda struktura ma już więc swoją odpowiedzialność. Nic nie stoi zatem na przeszkodzie, aby kolejna taka struktura realizowała zadanie wyszukiwania pełnotekstowego. Niestety, żadna z dostępnych struktur popularnych silników baz danych nie realizuje tego zadania w sposób na tyle dobry, aby móc go polecić.

Poza tym idąc tym tropem możemy dojść do wniosku, że nie potrzebujemy nic innego poza bazą danych. W imię zasady pojedynczej odpowiedzialności pozostawmy jednak bazom danych odpowiedzialność za przechowywanie oraz udostępnianie danych.

Sphinx jest jednym z rozwiązań, na które można przenieść odpowiedzialność za indeksowanie oraz wyszukiwanie pełnotekstowe. Alternatywnym rozwiązaniem może być Apache Lucene (lub rozszerzenie Apache Solr).

Sphinx jako indekser + searcher

Sphinx składa się z dwóch aplikacji: indeksera (indexer) oraz searchera (searchd). Indekser pozwala w oparciu o plik konfiguracyjny wyłuskać dane z bazy, zbudować na tej podstawie indeks oraz udostępnić go searcherowi. Searcher domyślnie uruchamiany jest jako daemon, który nasłuchuje na porcie 3312. Searcher odpowiada na zapytania, które do niego trafiają np. z linii komend lub ze skryptu.

Jeśli mielibyśmy rozpatrywać przykład sklepu sprzedającego narty, moglibyśmy ustalić, że zapytanie, z którego korzysta indekser wyglądałoby następująco:

source produkty_src { SELECT id, product_name, product_desc FROM products; }

Sphinx w momencie indeksowania wybiera wszystkie rekordy z tabeli products i na tej podstawie buduje swój indeks. Następnie w toku wyszukiwania to searcher wyda zapytanie do tak przygotowanego indeksu, a w odpowiedzi otrzyma listę ID, które spełniają kryteria. Właściwe zapytanie do bazy danych przyjmie zatem poniższą postać:

SELECT product_name, product_desc FROM products WHERE id IN (23, 56, 66, 79);

Zamiennie do zapytania, które z tego mechanizmu nie korzysta, a próbuje zwrócić podobny wynik:

SELECT product_name, product_desc FROM products WHERE product_name LIKE ‘%kurtka z kapturem%’ OR product_desc LIKE ‘%kurtka z kapturem%’ OR product_name LIKE ‘%kurtki z kapturem%’ OR …

Jeżeli w sklepie udostępniamy bardziej zaawansowaną wyszukiwarkę, tworzymy kilka indeksów, później zaś korzystamy z nich wg potrzeb:

source narty_src { SELECT id, product_name, product_desc \ FROM products WHERE type=’narty’; } source kurtki_src { SELECT id, product_name, product_desc \ FROM products WHERE type=’kurtki’; }

Siłę tego rozwiązania najłatwiej docenić korzystając z wyszukiwarki prosto z linii poleceń:

$ search "kurtki Descente"

Gdzie w wyniku uzyskamy:

Sphinx VERSION-release (R0001) Copyright (c) 2001-2XXX, Andrew Aksyonoff Copyright (c) 2008-2XXX, Sphinx Technologies Inc (http://sphinxsearch.com) using config file '/etc/sphinxsearch/sphinx.conf'... index 'narty_idx': query 'kurtki Descente ': returned 0 matches of 388 total in 0.023 sec index 'kurtki_idx': query 'kurtki Descente': returned 10 matches of 10 total in 0.000 sec displaying matches: 1. document=2456, weight=1622 2. document=3370, weight=1622 3. document=5213, weight=1622 4. document=5215, weight=1622 5. document=11797, weight=1622 6. document=12169, weight=1622 7. document=13601, weight=1622 8. document=13867, weight=1622 9. document=15924, weight=1622 10. document=16874, weight=1622 words: 1. 'Descente': 12 documents, 26 hits 2. 'kurtki': 116 documents, 136 hits

Wspomnieć warto o przypisywaniu wag do poszczególnych pól (np. słowo kurtka użyte w nazwie produktu ma większą wagę od słowa kurtka użytego w opisie). Sphnix tworzy również zapis każdego wyszukiwania w postaci pliku z logami, w których odnajdziemy szukane frazy wraz z informacją, jak wiele wyników zostało zwróconych. Zebrane dane mogą pozowolić na optymalizację sprzedaży w postaci dobrania oferty według oczekiwań klientów.

Podsumowanie

Poprawna konfiguracja Sphinxa powinna sprostać nawet najbardziej wymagającym wymaganiom. Wspomnieć należy o takich możliwościach jak bieżąca lub cykliczna reindeksacja czy wsparcie polskiego słownika, dzięki czemu oprócz słowa kurtka zostaną wyszukane słowa kurtki, kurtkami, kurtek, kurtkom itd.

Na szczególną uwagę zasługuje również rozdzielenie odpowiedzialności za przechowywanie i wyszukiwanie danych pomiędzy bazę danych oraz zewnętrzny mechanizm. Rzutuje to na zwiększoną wydajność bazy danych, którą odciążamy od żmudnej pracy wyszukiwania rekordów. Użycie Sphnixa wspomaga również utrzymanie oraz diagnostykę aplikacji. Z uwagi na wspomniane wsparcie polskiego słownika przekłada się także na zadowolenie użytkowników i klientów naszych stron WWW wynikające z szybszych i dokładniejszych wyników wyszukiwania.

Wyszukiwarki
Dodano dn. 17 lutego 2013 roku przez rado.