11 marca 2025 (updated: 11 marca 2025)
Chapters
Zobacz, jak wyświetlać dane i wdrożyć Geoserach na mapie MapBox przy użyciu Algolia.
W poprzednim artykule: Niestandardowe mapy w aplikacjach internetowych przy użyciu Mapbox i Mapbox Studio, omówiliśmy, jak stworzyć niestandardowy styl mapy przy użyciu Mapbox Studio, a następnie zintegrować Mapbox z projektem napisanym w frameworku Next.js przy użyciu biblioteki Mapbox GL JS.
W tym artykule rozwiniemy tę wiedzę i porozmawiamy o tym, jak wyświetlać dane na mapie w oparciu o nasz obszar geograficzny przy użyciu Algolia.
Na początek wyjaśnijmy, czym jest Algolia. Krótko mówiąc, Algolia to dostawca usług internetowych, który koncentruje się na przechowywaniu danych i obsłudze wyszukiwarek internetowych. Jest szczególnie przydatna w sytuacjach, gdy potrzebujemy szybkiej dostawy konkretnych funkcji, takich jak wyszukiwanie, rekomendacje itp.
Dzięki zastosowaniu algorytmów AI, sugestie i wyniki wyszukiwania stają się lepsze z każdym zapytaniem użytkownika, co sprawia, że silnik Algolia bardzo szybko odpowiada na zapytania. Dodatkowo oferuje funkcjonalności takie jak spersonalizowane wyniki wyszukiwania, system rekomendacji i analiza danych.
Programiści coraz częściej decydują się na wykorzystanie Algolia w swoich projektach, ponieważ umożliwia to bardzo szybkie dostarczanie wyszukiwarek i rekomendacji bez potrzeby tworzenia niezbędnej infrastruktury od podstaw. To bardzo dobra opcja w aplikacjach takich jak e-commerce.
Geo Search, jak sama nazwa wskazuje, jest ściśle związane z współrzędnymi geograficznymi i wyszukiwaniem. Jak już wiemy, Algolia oferuje usługi związane z obsługą silników wyszukiwania, a dzięki funkcjonalnościom takim jak Geo Search, umożliwia sortowanie i filtrowanie naszych wyników na podstawie współrzędnych geograficznych. Możemy również filtrować nasze odpowiedzi na podstawie współrzędnych użytkownika (na podstawie ich IP) lub współrzędnych obszaru geograficznego (ograniczone pudełka).
Aby Algolia mogła filtrować na podstawie współrzędnych, nasze dane muszą spełniać jeden wymóg. Konkretnie, każdy obiekt musi mieć atrybut o nazwie _geoloc, który będzie przechowywał informacje o lokalizacji w postaci szerokości geograficznej i długości geograficznej.
Zanim zaczniemy korzystać z Algolia, musimy najpierw założyć konto. Przejdź więc na stronę internetową i zarejestruj się. Algolia oferuje darmowy plan, w ramach którego możemy wykonać do 10 000 zapytań miesięcznie bez podpinania karty.
Po zarejestrowaniu się i zalogowaniu, zostaniemy poproszeni o utworzenie pierwszego indeksu. Indeks to miejsce, w którym przechowywane są dane. Możemy tworzyć wiele indeksów. W ten sposób, w sytuacjach, gdy na przykład chcemy ustawić wyszukiwanie dla dwóch typów danych oddzielnie lub użyć różnych strategii rankingowych dla każdego z nich, możemy to łatwo osiągnąć dzięki wielu indeksom.
Źródło: Algolia
Po krótkim czasie zostaniemy poproszeni o import danych. Kliknij więc na Upload your records. Jak wiemy, aby Geo Search działał, każdy obiekt powinien mieć pole _geoloc. Potrzebujemy więc danych, które spełnią ten warunek. Kliknijmy na Dodaj ręcznie i dodajmy kilka przykładowych danych. Pamiętaj, że dane muszą być w formacie JSON.
Aby lepiej zademonstrować działanie Algolia i Mapbox, w naszym przypadku użyjemy gotowego zestawu danych dostępnego na Algolia Github. Jest to zbiór głównych lotnisk na świecie. Skopiuj dane z pliku JSON i wklej je w odpowiednie miejsce.
Jeśli wszystko pójdzie dobrze, zostaniemy przeniesieni do głównego panelu Algolia.
Źródło: Algolia
Jak widać na załączonym zrzucie ekranu, główny panel Algolia oferuje nam wiele opcji. Polecam przeglądanie dostępnych opcji i sprawdzenie samemu, co oferuje Algolia. W naszym przypadku skupimy się tylko na rzeczach związanych z filtrowaniem według współrzędnych, ponieważ nie chcemy, aby ten artykuł miał 80 stron.
Każdy rekord w naszej bazie danych ma pole _geoloc. W ten sposób silnik Algolia będzie w stanie filtrować dane na podstawie podanych kryteriów. Jednak zanim to zrobimy, musimy poinformować Algolia o konkretnych polach, na podstawie których chcemy filtrować nasze dane.
Przejdź więc do Configuration -> Searchable attributes. Następnie dodaj nasze atrybuty _geoloc.lat i _geoloc.long do atrybutów wyszukiwalnych i zapisz.
Przejdźmy teraz do kodu. Jak wspomniałem na początku, jako podstawowe ustawienie użyjemy projektu stworzonego w poprzednim artykule dostępnym tutaj: Niestandardowe mapy w aplikacjach internetowych z użyciem Mapbox i Mapbox Studio. Jeśli nie interesuje Cię, jak stworzyć własny styl mapy od podstaw, możesz pominąć pierwsze rozdziały i przejść od razu do części związanej z kodem.
Ok, mamy nasz projekt. Zacznijmy od zainstalowania niezbędnych bibliotek. Najważniejszą rzeczą, której potrzebujemy, jest Algolia’s JavaScript API Client. To biblioteka, która pozwoli nam komunikować się z API Algolia na poziomie kodu. Dodatkowo zainstalujemy również bibliotekę React-Query, która da nam dostęp do hooków umożliwiających pobieranie i buforowanie danych, między innymi. To świetna biblioteka i gorąco polecam ją sprawdzić.
Najpierw stwórz klasę AlgoliaApi, która będzie odpowiedzialna za komunikację z API Algolia. Na razie będziemy potrzebować tylko metod do pobierania danych, ale nic nie stoi na przeszkodzie, aby w przyszłości rozszerzyć klasę o metody do przesyłania lub aktualizowania danych. Stwórzmy więc folder /api w głównym katalogu naszego projektu, a w nim plik o nazwie Algolia.ts. Aby komunikować się z Algolia, musimy najpierw stworzyć klienta z odpowiednimi appId, appKey i indexName. Jednak nie chcemy robić tego bezpośrednio w naszej klasie, ponieważ chcemy mieć możliwość używania wielu zbiorów danych Algolia w przyszłości.
Przyjmijmy więc SearchClient i indexName jako parametry w konstruktorze naszej klasy i zainicjalizujmy indeks.
Stwórzmy również metodę o nazwie getAirports, która wykorzysta klienta Algolia do pobrania danych z usługi Algolia. Przyjmuje jeden parametr, boundingBox (geograficzne krawędzie widocznego obszaru na mapie), który będziemy pobierać dynamicznie z naszej mapy w miarę jej przesuwania.
Dodajmy również podstawowe typy i interfejsy. Cały plik powinien wyglądać tak.
Ok, mamy naszą klasę API. Teraz stwórzmy hook, w którym ją wykorzystamy. Użyjemy do tego wcześniej wspomnianego React-Query. Jednak aby react-query działało, musimy owinąć naszą całą aplikację w QueryClientProvider. Możemy to zrobić w pliku _app.tsx.
W folderze Api stwórzmy plik o nazwie hooks.ts, a w nim hook o nazwie useAlgolia. Na początku stwórz instancję naszej klasy AlgoliaApi z odpowiednimi argumentami - algoliaClient i indexName. AppId i AppKey to zmienne konfiguracyjne, które można znaleźć w głównym panelu Algolia w Ustawienia -> Klucz API. IndexName, jak sama nazwa wskazuje, to nazwa naszego indeksu. Stwórzmy również metodę o nazwie useAirportsData, która jest wrapperem wokół hooka useQuery dostarczanego przez React-Query. Jako queryFn przekaż metodę getAirports z naszej klasy AlgoliaApi. Hook powinien wyglądać tak.
Prawie wszystko mamy. Stwórzmy jeszcze jeden hook o nazwie useDebounce. Wyjaśnię, dlaczego naprawdę go potrzebujemy później. W głównym katalogu stwórz folder o nazwie utils i w nim wcześniej wspomniany plik. Cały plik powinien wyglądać tak.
Więc mamy naszą klasę API, mamy hook, który pobierze nam dane, teraz możemy przejść do naszego komponentu mapy. W porównaniu do poprzedniego artykułu, musimy wprowadzić kilka zmian.
Na stronie biblioteki React-map-gl możemy sprawdzić, jakie propsy komponent Map może przyjmować. Jest ich wiele i polecam zapoznać się z nimi samodzielnie. W naszym przypadku skupimy się na propie o nazwie onRender. Callback będzie wywoływany za każdym razem, gdy mapa jest ponownie rysowana na ekranie, co dokładnie potrzebujemy, aby uzyskać aktualne granice mapy. Stwórz więc funkcję o nazwie onRender, w której wyodrębniamy aktualne granice mapy z parametru event. Następnie zaktualizuj nasz stan, pamiętając o użyciu właściwej kolejności.
Powiedziałem wcześniej, że wrócimy do hooka useDebounce. Zróbmy to teraz. Ponieważ każdy ruch mapy wywoła callback onRender wiele dziesiąt razy, a następnie zaktualizuje nasz stan, co wywoła zapytanie do serwera Algolia, musimy to w jakiś sposób zoptymalizować. Podczas przesuwania mapy nie musimy wysyłać zapytania przy każdym wywołaniu funkcji onRender, ale tylko na ostatnim, tuż przed zatrzymaniem mapy. W tym przypadku nasz hook jest idealny. Więcej informacji na temat debouncingu można znaleźć tutaj.
Ostatnią rzeczą, której potrzebujemy, jest właściwie renderowanie danych, które pobraliśmy i wyświetlenie ich na mapie. Użyjemy naszego hooka useAlgolia do tego, z którego zaimportujemy funkcję useAirportsData i przekażemy jej nasze geograficzne granice mapy. Aby renderować wyniki na mapie, użyjemy komponentu Marker z biblioteki react-map-gl. Zarówno funkcja onRender, jak i generowanie naszych znaczników będą owinięte w useCallback i useMemo, aby zapobiec niepotrzebnym ponownym renderowaniom. Cały komponent powinien wyglądać tak.
Tak wygląda nasza mapa z pobranymi danymi. Kiedy przewijamy, możemy zauważyć, że dane są pobierane tylko z obszaru, który aktualnie widzimy na mapie, i to dokładnie to, czego chcieliśmy!
Ale poczekaj, widzimy, że nasze dane są wyświetlane w nieco dziwny sposób. Wyświetlamy wiele lotnisk w jednym kraju i tylko jedno w innych, jak na przykład we Francji. Musimy jakoś posortować nasze wyniki. Na szczęście w Algolia jest to bardzo proste. Wszystko, co musimy zrobić, to przejść do Konfiguracja -> Ranking i Sortowanie i naciskając przycisk Dodaj atrybut sortowania, dodać atrybut links-count do atrybutów, według których sortujemy nasze dane. Jak widać poniżej, lotniska są wyświetlane w lepszy sposób.
Jak widzimy, Algolia to bardzo fajne i proste narzędzie, a konfiguracja w środowisku JS jest bardzo łatwa. Musimy jednak pamiętać, że rzeczy pokazane w tym artykule to tylko wierzchołek góry lodowej funkcjonalności, które oferuje nam Algolia. Warto zapoznać się z dokumentacją i sprawdzić, co jeszcze zespół Algolia ma do zaoferowania. Szczególnie zwróć uwagę na część związaną z Search UI, ponieważ Algolia nie tylko pozwala nam zarządzać wynikami wyszukiwania itp., ale także umożliwia budowanie całego interfejsu użytkownika opartego na wyszukiwaniu i tworzenie własnych widgetów.
11 marca 2025 • Maria Pradiuszyk
11 marca 2025 • Maria Pradiuszyk