Jak wdrożyć wyszukiwarkę pełnotekstową dla katalogu branżowego
Redakcja 1 sierpnia, 2026Technologia ArticleWyszukiwarka w katalogu branżowym nie może działać jak zwykłe polecenie SQL z warunkiem LIKE '%fraza%'. Użytkownik wpisuje „serwis klimatyzacji Wrocław”, „księgowa spółki zoo” albo nazwę firmy z literówką i oczekuje trafnych wyników w ułamku sekundy. Baza danych przechowuje jednak osobno nazwę, kategorię, opis, miasto, dzielnicę, usługi i dane adresowe. Bez osobnego indeksu wyszukiwania wyniki szybko stają się przypadkowe, a czas odpowiedzi rośnie wraz z katalogiem.
Dobrze wdrożona wyszukiwarka pełnotekstowa powinna rozwiązać cztery problemy jednocześnie: rozumieć odmiany polskich słów, tolerować rozsądne literówki, uwzględniać lokalizację i ustawiać najbardziej użyteczne firmy wyżej niż wpisy tylko przypadkowo zawierające szukaną frazę. Sam wybór silnika jest dopiero początkiem. Najwięcej pracy wymaga przygotowanie danych oraz ustalenie, co właściwie oznacza „trafny wynik”.
Najpierw zaprojektuj dokument wyszukiwania, nie ekran z lupą
Każda firma powinna trafiać do indeksu jako jeden uporządkowany dokument. Nie należy kopiować całego rekordu z relacyjnej bazy danych. Indeks ma zawierać tylko pola potrzebne do wyszukiwania, filtrowania, sortowania i prezentacji wyniku.
Przykładowy dokument może obejmować:
company_id— trwały identyfikator firmy,name— nazwa handlowa,categories— kategorie i podkategorie,services— konkretne usługi,description— opis działalności,city,district,voivodeship— lokalizacja administracyjna,address— ulica i numer,latitude,longitude— współrzędne,verified— status weryfikacji,ratingireviews_count— ocena oraz liczba opinii,updated_at— data ostatniej aktualizacji,is_active— informacja, czy wizytówka powinna być widoczna.
Najczęstszy błąd polega na wrzuceniu nazwy, opisu, kategorii i adresu do jednego pola tekstowego. Silnik nie potrafi wtedy odróżnić sytuacji, w której „hydraulik” jest główną kategorią firmy, od przypadku, gdy słowo pojawia się raz w długim opisie. Nazwa firmy, kategoria, usługa i opis powinny mieć osobne wagi.
Rozsądny punkt startowy dla funkcji punktującej wygląda następująco:
- nazwa firmy: waga 5,
- główna kategoria: waga 4,
- lista usług: waga 3,
- podkategorie: waga 2,
- opis: waga 1,
- dokładne dopasowanie miasta: dodatkowe wzmocnienie,
- zweryfikowana wizytówka: niewielki bonus,
- nieaktywna firma: całkowite wykluczenie.
Nie należy od razu przyznawać dużego bonusu za płatny pakiet, liczbę opinii czy ocenę. Gdy czynnik biznesowy dominuje nad dopasowaniem tekstowym, użytkownik wpisujący „naprawa pomp ciepła” zaczyna dostawać wysoko ogólne firmy instalacyjne tylko dlatego, że wykupiły promocję. Reklama może mieć własną sekcję, ale organiczny ranking wyszukiwarki powinien zachować wiarygodność.
Trzeba też zdecydować, które dane są filtrem, a które częścią tekstu. Województwo, miasto, status aktywności, przedział ocen czy dostępność konkretnej usługi dobrze działają jako filtry. Opis działalności powinien być analizowany pełnotekstowo. Numer telefonu, NIP i kod pocztowy wymagają dopasowania dokładnego, bez odmiany i bez tolerancji literówek.
Dane należy normalizować jeszcze przed indeksowaniem. W praktyce oznacza to między innymi:
- zamianę wielokrotnych spacji na pojedyncze,
- ujednolicenie skrótów „al.”, „aleja” i „Aleje”,
- przechowywanie nazw miast w jednej kanonicznej formie,
- oddzielenie kodu pocztowego od adresu,
- usunięcie HTML-u z opisów,
- ograniczenie powtarzania słów kluczowych,
- odrzucenie pustych i automatycznie wygenerowanych opisów.
Indeks nie naprawi bałaganu w katalogu. Gdy jedna firma ma kategorię „budownictwo”, druga „usługi budowlane”, a trzecia „remonty i wykończenia”, wyszukiwarka będzie próbowała zgadywać relacje, które powinny wynikać ze słownika kategorii.
Wybierz silnik pod skalę i poziom kontroli
Dla niewielkiego katalogu nie zawsze trzeba uruchamiać osobny klaster. PostgreSQL oferuje wyszukiwanie pełnotekstowe, ranking, słowniki, indeksy GIN oraz rozszerzenie pg_trgm, które pomaga obsługiwać podobieństwo napisów i literówki. Przy katalogu liczącym kilkadziesiąt tysięcy firm jest to często najtańszy i najszybszy sposób uruchomienia pierwszej wersji.
PostgreSQL ma sens, gdy:
- katalog zawiera do około 50–200 tys. dokumentów,
- liczba zapytań nie przekracza kilkunastu lub kilkudziesięciu na sekundę,
- zespół chce ograniczyć liczbę usług infrastrukturalnych,
- ranking nie wymaga skomplikowanych reguł,
- wyszukiwanie odbywa się głównie po nazwie, kategorii i lokalizacji.
Granica nie wynika wyłącznie z liczby rekordów. Milion krótkich wizytówek może być łatwiejszy do obsłużenia niż 100 tys. profili z wieloma wersjami językowymi, rozbudowanymi filtrami i częstą aktualizacją. Trzeba mierzyć liczbę zapytań, wielkość indeksu, czas indeksowania i opóźnienie na 95. percentylu, a nie patrzeć wyłącznie na liczbę firm.
Przy większym katalogu najczęściej wybiera się Elasticsearch albo OpenSearch. Oba rozwiązania oferują między innymi wyszukiwanie BM25, pola wielowartościowe, filtry, agregacje, synonimy, fuzzy matching, wyszukiwanie geograficzne i rozbudowane sterowanie rankingiem. Ich przewagą jest elastyczność. Wadą — koszt utrzymania oraz liczba parametrów, które można ustawić źle.
Minimalny produkcyjny klaster nie powinien opierać się na pojedynczym węźle. Awaria jednej maszyny oznaczałaby utratę wyszukiwania, nawet gdy główna baza katalogu nadal działa. W środowisku produkcyjnym sensownym minimum są zazwyczaj dwa lub trzy węzły, replika indeksu, monitoring pamięci, automatyczne snapshoty i alerty dotyczące zajętości dysku.
Orientacyjne koszty małego klastra zarządzanego zwykle zaczynają się od około 300–800 zł miesięcznie, zależnie od dostawcy, regionu, pamięci, liczby węzłów i transferu. Konfiguracja z wysoką dostępnością, większą pamięcią oraz środowiskiem testowym łatwo przekracza 1000–3000 zł miesięcznie. Samodzielne uruchomienie na serwerach VPS obniża rachunek za infrastrukturę, ale przenosi na zespół aktualizacje, kopie zapasowe, reagowanie na przepełnienie dysku i odtwarzanie klastra po awarii.
Lżejszą alternatywą jest Meilisearch. Oferuje tolerancję literówek, facety, reguły rankingu, geowyszukiwanie i wyszukiwanie podczas pisania bez tak rozbudowanej konfiguracji jak Elasticsearch. Usługa chmurowa zaczyna się od około 20–30 USD miesięcznie, a mała instancja zasobowa od nieco ponad 20 USD. To dobry wybór dla zespołu, który potrzebuje szybkiego wdrożenia i nie planuje budować skomplikowanego modelu punktowania.
Ograniczenie Meilisearch ujawnia się wtedy, gdy ranking wymaga wielu niestandardowych warunków, precyzyjnego strojenia analizatorów językowych albo zaawansowanych agregacji. Narzędzie upraszcza wdrożenie, ale część kontroli oddaje się w zamian za tę prostotę.
Praktyczna ścieżka wyboru wygląda tak:
- PostgreSQL +
pg_trgm— pierwsza wersja, niski koszt i umiarkowana skala; - Meilisearch — szybkie wyszukiwanie aplikacyjne z filtrami i tolerancją literówek;
- OpenSearch — duża kontrola, otwarte rozwiązanie i możliwość samodzielnego hostowania;
- Elasticsearch — rozbudowany ekosystem, zaawansowany ranking i integracje, ale zwykle najwyższy koszt operacyjny.
Nie należy zaczynać od wyszukiwania semantycznego ani modeli embeddingowych. Dla zapytań typu „dentysta dziecięcy Gdańsk Wrzeszcz” dobrze skonfigurowane wyszukiwanie leksykalne z filtrami geograficznymi jest tańsze, prostsze do wyjaśnienia i zazwyczaj bardziej przewidywalne. Wektory warto dodać dopiero wtedy, gdy analiza logów pokaże wiele zapytań opisowych, na przykład „firma, która odbierze gruz po remoncie”, których klasyczny słownik nie obsługuje wystarczająco dobrze.
Ranking, polski język i synchronizacja decydują o jakości
Użytkownik nie ocenia technologii indeksu. Ocena jest prostsza: czy pierwsze pięć wyników odpowiada zapytaniu. Dlatego wdrożenie trzeba rozpocząć od zestawu testowego, a nie od strojenia parametrów na wyczucie.
Dobry zestaw powinien zawierać przynajmniej 100–300 rzeczywistych zapytań podzielonych na grupy:
- nazwy firm,
- kategorie ogólne,
- konkretne usługi,
- usługi połączone z miastem,
- zapytania z dzielnicą,
- literówki,
- skróty,
- nazwy potoczne,
- zapytania bez wyników,
- zapytania wieloznaczne.
Dla każdego zapytania należy ręcznie oznaczyć oczekiwane firmy lub przynajmniej oczekiwaną kategorię i lokalizację. Bez tego nie da się stwierdzić, czy zmiana rankingu rzeczywiście pomaga. Kliknięcia użytkowników są ważne, ale nie mogą być jedynym miernikiem. Pierwszy wynik z natury dostaje więcej kliknięć, nawet gdy jest przeciętny.
W języku polskim samo sprowadzenie liter do małych znaków nie wystarcza. Wyszukiwarka musi radzić sobie z formami takimi jak „księgowy”, „księgowa”, „księgowość” i „biuro księgowe”. Stemming może pomóc przy odmianie, ale zbyt agresywne skracanie wyrazów potrafi łączyć pojęcia, które biznesowo nie powinny być traktowane identycznie. Dlatego lepiej utrzymywać równolegle:
- pole z tekstem analizowanym językowo,
- pole z analizą prostą,
- pole typu
keyworddo dopasowania dokładnego, - własny słownik synonimów branżowych.
Synonimy powinny wynikać z danych katalogu i logów wyszukiwania. Przykładowo „mechanik”, „warsztat samochodowy” i „serwis aut” mogą prowadzić do zbliżonych wyników. Nie są jednak zawsze wymienne. „Serwis opon” nie powinien automatycznie stawać się pełnym synonimem „mechanika”, bo część zakładów zajmuje się wyłącznie ogumieniem.
Szczególnej ostrożności wymaga tolerancja literówek. Dystans edycyjny ustawiony zbyt szeroko zwiększa liczbę wyników, ale obniża ich jakość. Krótkie zapytania, takie jak „bar”, „gaz” czy „tax”, nie powinny być poprawiane równie agresywnie jak dłuższe nazwy. Dobra reguła startowa to:
- brak tolerancji dla wyrazów do 3 znaków,
- jedna zmiana dla wyrazów liczących 4–7 znaków,
- maksymalnie dwie zmiany dla dłuższych wyrazów,
- preferowanie dokładnego dopasowania przed wynikiem rozmytym.
Lokalizacja również nie powinna być zwykłym słowem w opisie. Gdy użytkownik wybierze Poznań z filtra, firmy spoza Poznania należy wykluczyć albo świadomie pokazać w osobnej sekcji. Jeżeli nie wybierze miasta, można wykorzystać jego lokalizację, lecz wyłącznie za zgodą i z wyraźną możliwością zmiany obszaru.
W katalogach usługowych dobrze działa sortowanie po odległości, ale tylko jako jeden z czynników. Firma oddalona o 700 metrów, która nie wykonuje szukanej usługi, nie powinna wyprzedzać specjalisty znajdującego się trzy kilometry dalej. Najpierw zgodność kategorii i usługi, później odległość.
Indeks musi pozostawać zsynchronizowany z główną bazą danych. Są trzy popularne metody:
- Synchronizacja bezpośrednia po zapisie — aplikacja aktualizuje bazę i od razu wysyła dokument do silnika. Jest prosta, ale awaria wyszukiwarki może blokować zapis albo powodować rozjazd danych.
- Kolejka zdarzeń — zapis do bazy tworzy komunikat obsługiwany przez osobny proces. To bezpieczniejszy wariant produkcyjny, pod warunkiem że kolejka ma ponawianie, rejestr błędów i mechanizm usuwania duplikatów.
- Okresowe pełne indeksowanie — łatwe do wdrożenia, lecz przy dużym katalogu kosztowne i opóźniające aktualizacje.
Najpraktyczniejszy model to kolejka aktualizacji połączona z nocnym procesem kontrolnym. Aktualizacje trafiają do indeksu zwykle w ciągu kilku sekund, a raz na dobę system porównuje identyfikatory i wykrywa brakujące lub nieaktualne dokumenty.
Trzeba też zaprojektować pełne przebudowanie indeksu bez przestoju. Tworzy się nowy indeks z numerem wersji, na przykład companies_v12, ładuje dane, wykonuje testy, a następnie przepina alias companies_current. Usunięcie starego indeksu następuje dopiero po potwierdzeniu, że nowa wersja działa prawidłowo. Nadpisywanie jedynego aktywnego indeksu w miejscu jest ryzykowne: błąd mapowania albo przerwany import może wyłączyć wyszukiwanie na wiele godzin.
Logi powinny zapisywać co najmniej:
- treść zapytania,
- wybrane filtry,
- liczbę wyników,
- czas odpowiedzi,
- identyfikatory pierwszych wyników,
- kliknięty wynik i jego pozycję,
- zapytania bez kliknięcia,
- zapytania bez wyników.
Najbardziej użyteczny raport nie pokazuje średniego czasu odpowiedzi, lecz 95. i 99. percentyl. Średnia może wynosić 80 ms, podczas gdy część użytkowników regularnie czeka ponad sekundę. Dla katalogu branżowego rozsądnym celem jest odpowiedź backendu poniżej 200–300 ms dla 95% zapytań. Cały interfejs może być wolniejszy przez sieć i renderowanie, dlatego te czasy należy mierzyć osobno.
Jakość wyników zależy również od samych profili firm. Puste opisy, błędne kategorie, duplikaty adresów i nieaktualne numery telefonów psują ranking niezależnie od silnika. Dane NAP — nazwa, adres i telefon — powinny być spójne zarówno wewnątrz katalogu, jak i w pozostałych miejscach publikacji firmy. Więcej informacji na: wizytówki NAP – aiqo.pl.
FAQ
Czy MySQL wystarczy do wyszukiwania pełnotekstowego?
Może wystarczyć dla prostego katalogu i niewielkiego ruchu, ale kontrola rankingu, obsługa polskich odmian, literówek, geolokalizacji i rozbudowanych filtrów będzie ograniczona. Przy rozwijanym katalogu lepszym etapem przejściowym jest PostgreSQL z indeksami GIN i pg_trgm.
Ile trwa wdrożenie pierwszej wersji?
Prototyp oparty na istniejących, uporządkowanych danych można uruchomić w około 3–7 dni roboczych. Produkcyjna wersja z kolejką synchronizacyjną, monitoringiem, testami rankingu, obsługą synonimów i bezprzerwowym reindeksowaniem zwykle wymaga 3–6 tygodni.
Czy wyszukiwarka powinna działać po każdym znaku?
Nie zawsze. Wysyłanie zapytania po pierwszej literze generuje dużo ruchu i słabe wyniki. Najczęściej lepiej rozpocząć wyszukiwanie po 2–3 znakach oraz zastosować opóźnienie debounce rzędu 200–350 ms.
Jak często aktualizować indeks?
Zmiany istotne dla użytkownika, takie jak wyłączenie firmy, zmiana telefonu czy kategorii, powinny pojawiać się po kilku lub kilkunastu sekundach. Pełna kontrola zgodności indeksu z bazą może być wykonywana raz na dobę.
Czy warto od razu wdrożyć wyszukiwanie semantyczne?
Nie. Najpierw trzeba poprawnie skonfigurować pola, wagi, filtry, lokalizację, synonimy i literówki. Wyszukiwanie semantyczne ma sens dopiero po zebraniu logów pokazujących, że użytkownicy często wpisują opisowe pytania, których klasyczny indeks nie obsługuje.
Co zrobić z zapytaniami bez wyników?
Nie wyświetlać od razu pustej strony. System powinien kolejno sprawdzić literówkę, synonim, szerszą kategorię i większy obszar geograficzny. Rozszerzenie wyszukiwania musi być jednak oznaczone, na przykład komunikatem „Brak wyników w dzielnicy — pokazujemy firmy z całego miasta”.
Czy wyniki można układać według ocen?
Ocena powinna być czynnikiem pomocniczym, nie głównym. Profil z oceną 5,0 na podstawie jednej opinii nie powinien automatycznie wyprzedzać firmy z oceną 4,8 i 180 opiniami. Najpierw należy sprawdzić dopasowanie do zapytania, później wiarygodność oceny.
Pierwszym działaniem nie powinien być wybór Elasticsearcha, OpenSearcha ani Meilisearch. Najpierw wyeksportuj 100 najczęstszych zapytań z obecnego katalogu, ręcznie przypisz do nich oczekiwane wyniki i sprawdź, czy dane firm mają jednolite kategorie, lokalizacje oraz nazwy usług. Jeżeli katalog nie ma takich logów, zacznij je zbierać jeszcze przed wdrożeniem. Najdroższy błąd to budowa zaawansowanego indeksu bez ustalonej definicji trafności — wtedy zespół stroi parametry, ale nie potrafi zmierzyć, czy wyszukiwarka działa lepiej.
You may also like
Najnowsze artykuły
- Mleko skondensowane z ube: jak używać go do latte i deserów, jak ograniczyć nadmierną słodycz i przechowywać puszkę po otwarciu
- Konsultacja estetyczna bez pośpiechu: jakie informacje pomagają dobrać rozsądny plan zabiegowy
- Jak wdrożyć wyszukiwarkę pełnotekstową dla katalogu branżowego
- Jak udostępnić katalog firm agentom AI przez uporządkowany interfejs
- Jak w wizytówce NAP zapisać adres firmy działającej na terenie parku przemysłowego
Najnowsze komentarze
Archiwa
- sierpień 2026
- lipiec 2026
- czerwiec 2026
- maj 2026
- kwiecień 2026
- marzec 2026
- luty 2026
- styczeń 2026
- grudzień 2025
- listopad 2025
- październik 2025
- wrzesień 2025
- sierpień 2025
- lipiec 2025
- czerwiec 2025
- maj 2025
- kwiecień 2025
- marzec 2025
- luty 2025
- styczeń 2025
- grudzień 2024
- listopad 2024
- październik 2024
- wrzesień 2024
- sierpień 2024
- lipiec 2024
- czerwiec 2024
- maj 2024
- kwiecień 2024
- marzec 2024
- luty 2024
- styczeń 2024
- grudzień 2023
- listopad 2023
- październik 2023

Dodaj komentarz