Techniki Zaawansowane
3 godz. 43 min · Python · Full-stack i Programowanie
Grzegorz SzymborskiProgramistaJeżeli na samym początku nie przygotujemy dobrze projektu, to gdy wrócimy do niego po dłuższym czasie - czekają nas kłopoty. Jeżeli uda się nam go uruchomić, to rozeznanie się w nim będzie udręką. Prowadzący pokaże Ci jak wyglądają jego produkcyjne aplikacje, na co zwraca uwagę i co pomaga mu trzymać porządek.
Biblioteka pytest posiada wiele ciekawych funkcjonalności. Parametryzowanie testów, fixture i uproszczona składnia pozwalają nam skupić na testowaniu tego, co kluczowe, wydzielając mniej istotne fragmenty kodu. To wszystko sprawia, że w pewnym momencie łatwiej będzie Ci pisać testy, niż ręcznie sprawdzać poprawność działania apki.
Jeżeli aplikacja, którą stworzysz, osiągnie dużą popularność, może się okazać, że przytłoczona dużym ruchem zacznie spowalniać... lub całkowicie przestanie odpowiadać. Opiszemy różne techniki służące temu, by temu zaradzić - od metod select i prefetch related, aż po cache. Na deser przeprowadzimy na stronie test obciążeniowy za pomocą narzędzia locust.
Django i Postgres to świetne połączenie. Framework ten posiada wbudowaną obsługę wyszukiwania pełnotekstowego oferowanego przez tę bazę. Warto wiedzieć, kiedy jej użyć, a kiedy wystarczy zwykłe icontains.
ORM w Django ułatwia mnóstwo operacji. A czasem nie dość to, że ułatwia... to jeszcze przyspiesza! Chcemy zainspirować Cię czterema metodami: annotate, aggregate, bulkupdate i bulkcreate. Gdy pojawią się one w naszym kodzie, zaczniemy doceniać uroki frameworka Django.
Kurs jest stworzony dla osób, które znają już podstawy Django i wiedzą, jak pisać proste strony. Znają modele, widoki, oraz niestraszny im jest Python. Zalecana jest również podstawowa znajomość dowolnej relacyjnej bazy danych. W kursie przedstawiamy niekiedy narzędzia i praktyczne przykłady, jak można ich użyć, ale w celu zaimplementowania konkretnego rozwiązania w projekcie wymagana będzie umiejętność czytania dokumentacji.
W tej lekcji bliżej przyjrzymy się klasie SearchRank, która pozwala nam
na ocenienie jak dobre dopasowanie trafiliśmy dla danego wyszukiwania.
Przejdźmy do widoku z filtrem.
Widzimy, że skończyliśmy na Trigram Similarity, które zwracało nam
określony wskaźnik tego jak dobrze zostało dopasowane słowo.
Natomiast teraz.
Zmienimy to na klasę SearchRank.
Searchrank bierzemy z Django Country, pozwykle z Search.
I tutaj.
Jest nieco inaczej.
Pierwszym parametrem jest wektor.
Wektor będzie zawierał pola, po których będziemy wyszukiwać, a drugim parametrem
jest query, które nas interesuje, które wprowadzi użytkownik.
Zdefiniujemy sobie wektor.
Wektor w najprostszej swojej formie po prostu przyjmuje pole.
Pole w modelu, po którym będziemy
wyszukiwać, natomiast my sobie trochę utrudnimy sprawę i dodamy jeszcze wagę.
Waga będzie nam definiowała jak ważne jest to pole.
Wiadomo, że jeżeli wyszukujemy jakiegoś artykułu, to prędzej
zależy nam na tym, żeby w tytule właśnie znalazł się fragment, który nas
interesuje, niż był on gdzieś głęboko zaszyty w treści.
Dlatego waga tytułu będzie równa a.
Dodamy jeszcze drugi wektor, który będzie zawierał treść
artykułu i jego waga będzie z kolei mniejsza.
Będzie się równała b.
Zajrzymy do artykułu.
Mamy tytuł, mamy content.
Ten wektor umieszczamy zgodnie z tym co mówiłem wcześniej w
parametrze pierwszym a w drugim parametrze będziemy potrzebowali search query.
Search query jest to obiekt.
Klasę search query, który
przyjmuje stringa i tego stringa zamienia, weźmy tutaj query, zamienia go
na symbole, na analogiczne symbole jakie były w wektorze
i dzięki temu wyszukiwanie staje się bardziej naturalne dla bazy danych.
Przypiszmy to.
Nazwiemy nasz search rank jako rank.
I podobnie jak wcześniej, zaanotatujemy go.
Wejdźmy sobie do listy i wyświetlmy, co nam się tam pojawiło.
Zielona herbata została dopasowana niemal
idealnie, z kolei mleko i herbata czarna gdzieś blisko zera.
Jest to bardzo mała wartość.
Spróbujmy samą herbatę wyszukać i pokażę Wam o co chodzi z tym dopasowaniem.
Zobaczmy, że artykuł o liściach herbaty ma 0,3.
Artykuł zielona herbata pochodzi z Chin z kolei.
Jest dużo, dużo wyżej.
Dlaczego tak się dzieje?
Zobaczmy, że search vector z wagą a faworyzuje te pola.
Jeżeli.
Herbata znajduje się w tytule, to automatycznie ma dużo więcej punktów.
Zajrzymy w ogóle.
Jak to działa w środku.
Dlaczego herbata czarna ma większą punktację niż zielona herbata?
Wyszukajmy, ile razy powtarza się słówko herbata.
Jest to siedem razy.
Wejdźmy tutaj. Wyszukajmy.
Jest to pięć razy.
Dlatego widzimy mniej więcej jak liczba powtórzeń wpływa na punktację.
Zajrzyjmy jeszcze do ostatniego artykułu.
Tutaj mamy tylko dwa powtórzenia.
Dobrym pomysłem, kiedy już używamy
Search Ranka, jest posortowanie wyników od najlepiej dopasowanych,
ponieważ zazwyczaj użytkownikowi właśnie na takich zależy.
Możemy jeszcze wykluczyć te, które nie są w ogóle dopasowane za pomocą filtru.
Większe od zera.
W ten sposób wpisując herbata nie wyszukujemy już mleka.
Kiedy tworzymy wyszukiwarkę do naszego
projektu, dobrą praktyką jest poeksperymentowanie z dostępnymi metodami.
Czasem najlepszym rozwiązaniem będzie
zastosowanie kilku różnych technik, zarówno Search Ranka, jak i Trigram
Similarity, które stworzą nam średnią ważoną albo
wyciągniemy wtedy wartość, która jest większa.
Na przykład jeżeli Trigger będzie nam
bardziej odpowiadał, to wtedy weźmiemy jego wynik.
Jeżeli Search Rank, to wtedy jego.
Czasem wyszukiwarka jest też nieco inna.
Czasem potrzebujemy dokładnego wyszukiwania danej frazy.
Czasem wyszukujemy słów kluczowych, czasem konkretnych fraz.
Dlatego najlepszym.
Sposobem jest eksperymentowanie
i dopasowanie odpowiednich technik do naszego projektu.
Na podsumowanie rozdziału o wyszukiwarkach Chciałem opowiedzieć wam
o przypadku, kiedy wasza baza danych bardzo się
rozrośnie, kiedy liczba rekordów, po których będziecie
wyszukiwać, wzrośnie do setek, tysięcy, może nawet milionów.
Wtedy bardzo dobrym pomysłem, jeżeli używacie wektorów do wyszukiwania, jest
użycie Search Vector Fielda, dostępnego w Django i przypisywanie indeksów w momencie
zmiany danych, na przykład w sygnałach, aktualizowanie tego co jakiś
czas, bądź aktualizowanie tego po każdej zmianie.
Dobrym pomysłem jest też, a właściwie jest
to nieodzowne, jeżeli mamy naprawdę dużo danych, użycie indeksów.
Przypisujemy je w metaklasie za pomocą klasy GINIndex w atrybucie "indexes".
Pozwoli nam to na
10krotne, 20krotne, może nawet 100krotne przyspieszenie wyszukiwania danych.
Miałem taki przypadek, że wyszukiwanie bez indeksów trwało około 10 sekund, natomiast
po zaindeksowaniu odpowiednich pól udało się zejść do 100 milisekund.
Jeżeli wyszukiwanie pełnotekstowe dostępne
w Postgresie nam już nie wystarcza, możemy skorzystać z dedykowanych narzędzi.
Do. Wyszukiwania danych.
Jednym z nich jest na przykład Elasticsearch, który jest
tak rozbudowanym narzędziem, że można by było o nim nagrać osobny kurs.
Można z nim zrobić wszystko, co możecie sobie wyobrazić o wyszukiwaniu danych.
Z własnego doświadczenia mogę Wam jednak powiedzieć, że używanie go
do prostych zastosowań generuje dość dużo kłopotów.
Elasticsearch jest dość wymagający jeżeli chodzi o środowisko.
Wymaga dużo RAMu i jego konfiguracja nie należy również do najprostszych.
Ale jeżeli planujecie tworzyć system na
naprawdę dużą skalę, to jest to dobry kierunek.
Biblioteką, która pozwala wpiąć Elasticsearcha bądź inne
narzędzia do wyszukiwania takie jak Solr jest Django Highstack.