markonix
5.12.2012, 17:41:50
Myślę, że to dość powtarzający się problem i pewnie ma ktoś już jakieś doświadczenie.
Chodzi o wyszukiwarkę. Pomińmy może rozwiązania wymagające instalacji oprogramowania na serwerze czyli co MySQL daje w standardzie.
Prosto z mostu - co najlepiej użyć? Mamy dwie kolumny imię i nazwisko.
- CONCAT + LIKE %%
- AGAINST
- AGAINST BOOLEAN
- LEVENSTEIN
?
Pierwsze ok, w miarę działa ale nie posortuje wg trafności.
Z resztą nie mam doświadczenia dlatego pisze ten temat.
Czy w AGAINST (BOOLEAN) można dać większy priorytet dla danej kolumny np. nazwiska?
Np. Jeżeli ktoś się nazywa Jan Adam to chciałbym aby po wpisaniu "Adam" wyszukiwał najpierw osoby o nazwisku Adam, potem dopiero poszukał Adamów. Ogólnie nazwisko powinno mieć większy priorytet.
Potem fajnie by było dodawać dodatkowe punkty za dodatkowe wartości np. jeżeli wyszukana osoba jest z tej samej miejscowości. Czy tu da radę to zrobić na poziomie zapytania czy już wyniki uzupełniać w PHP?
alegorn
5.12.2012, 18:59:20
LEVENSTEIN jest do sprawdzenia odleglosci ciagow znakow, czyli jak nie znajdziesz takiego jak szukasz - to mozesz podpowiedziec/zalozyc ze chodzi prawdopodobnie o :..
jesli po dwu kolumnach i tylko wyszukiwarka - to nie bawilbym sie w AGAINST, tylko w zwykly index.
nie bardzo wiem jaki masz pomysl na to, tzn czego konkretnie szukasz, prawdopodobnie dopytujesz sie o jakis 'suggest'. to nie dokonca to samo co wyszukiwarka.
jesli chcesz podpowiadac mozliwe wyniki, to najlepiej bedzie jak zalozysz index i szukal po like 'ciag%', i tutaj opcjonalnie LEVENSTEIN, jesli nei znajdziesz niczego.
jesli dasz tylko prawostronnie '%' to nadal bedziesz mogl korzystac z indexow. jesli (choc nie wiem po co) musisz miec '%ciag%' to against match, ale radzilbym na silniku 5.6
tam mozna juz na innodb to wykorzystac.
jesli nie masz mozliwosci na 5.6 - to zastanawialbym sie nad rozwiazaniami typu np sphinx.
rozwiazania like '%ciag%' czy rlike 'ciag' nie maja mozliwosci korzystania z indeksow, wiec skanowanie jest po calej tabeli, czego za wszelka cene unikamy.
dodatkowo, jesli mozesz wykorzystac ciagi lewostronnie zamkniete, i tabela nie jest ogromnych rozmiarow, to sugerowalbym silnik memory (choc musisz znac wady tego!)
silnik memory, like 'ciag%' + indexy, bedzie najwydajniejsze.
jesli tabela jest ogromna, zamiast memory, dajesz innodb z partycjonowaniem tabeli, oczywiscie wg indexu, dziala wydajniej o rząd wielkosci, od jednej wielkiej tabeli.
hmmm, to na tyle, jesli chodzi o baze danych..
j.
edit:
nie doczytalem koncowki Twojego posta. zostawiam jednak bo kilka ciekawych uwag powinno dac sie tam odszukac.
jesli masz dwie kolumny, to musisz zadac dwa różne zapytania i zlaczyc po UNION, wpierw przeszukujac pole NAZWISKO.
sposob w jaki przeszukiwac po kolumnie - opisalem powyzej.
o co Ci chodzi z miejscowosciami - to juz nie zalapalem.
markonix
5.12.2012, 22:11:26
LEVENSTEIN ogólnie bym sobie darował żeby nie komplikować sprawy. Ktoś zrobi literówkę to już niech się martwi.
Przy uzupełnianiu dodam podpowiedzi przyjmując, że wpisywany ciąg to nazwisko, a następnie dopiero imię.
Co do miejscowości -> Szukasz Jan Kowalski. W bazie masz ich trzech, ale dwaj mieszkają nad morzem, a drugi obok Ciebie i jest z Twojej szkoły. Wtedy jak myślisz o którego Ci chodziło?

Oczywiście to tylko przykłady "punktowania". Słowo punktowanie wziąłem po prostu z aliasu "score", który zazwyczaj jest używany przy AGAINST.
http://stackoverflow.com/questions/6259647...-column#6305108Tutaj znalazłem fajne rozwiązanie, wymaga jedynie nałożenia dwóch indeksów (przynajmniej w moim przypadku).
Te rozwiązanie (sumowanie ratingów) podsunęło mi też od razu pomysł na dodanie punktów za jakieś tam cechy (za pomocą CASE).