Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Opis jak zrobić wyszukiwarkę z wyświetlaniem trafności
spenalzo
post
Post #1





Grupa: Zarejestrowani
Postów: 2 064
Pomógł: 1
Dołączył: 22.01.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Ponieważ zaciekawiło mnie to co napisał Dragossani w <b>tym</b>wątku, postudiowałem manual do MySQLa i oto co z tego wynikło - wyszukiwarkę z określaniem trafności można zrobić jednym zapytaniem :-)

<i><b>Jak zrobić wyszukiwarkę?</b></i>

Zacznijmy od początku:
zakładamy, że chcemy zrobić własną wyszukiwarkę do forum phpBB.
Na początku dodajemy do istniejącej tabeli prefix_posts_text jedno pole:
  1. ALTER TABLE prefix_posts_text ADD FULLTEXT (post_subject,post_text)

Jeżeli wszystko przebiegło pomyslne to możemy zająć się stworzeniem zapytania formularza wyszukiwania.
Do wyszukiwania używamy funkcji mysqla
  1. MATCH(col1,col2,..) AGAINST ('szukany_tekst')

która zwraca wyniki trafności wyszukiwania.

Teraz zróbmy z tego zapytanie:
  1. <?php
  2. $q=mysql_query(&#092;"SELECT MATCH(post_subject,post_text) AGAINST ('\".$_POST[\"f\"].\"') AS stopien, post_text, post_ID,post_subject FROM prefix_posts_text ORDER B
    Y
  3. stopien DESC&#092;") or die(mysql_error());?>

zakładając, że w zmiennej $_POST["f"] mamy szukane wyrażenie.

Jeżeli zapytanie działa, to jedziemy dalej, jeżeli nie to szukamy rozwiązania w manualu.
Teraz przypisujemy odpowiednie wartości do tablic:
  1. <?php
  2.  for($i=0; $i<mysql_num_rows($q); $i++)
  3.  {
  4. if($t[&#092;"stopien\"]>0)
  5. {
  6.  $stopnie[]=$t[&#092;"stopien\"];
  7.  $IDs[]=$t[&#092;"post_ID\"];
  8.  $sub[]=$t[&#092;"post_subject\"];
  9.  $post[]=$t[&#092;"post_text\"];
  10. }
  11.  }
  12. ?>


Teraz przygotujmy wyświetlanie wyników.
Ponieważ zwracane wyniki trafności nie są za każdym razem identyczne, wyszukujemy najwiekszą wartość:
  1. <?php
  2.  $max=$stopnie[@array_search(@max($stopnie),$stopnie)];
  3. ?>


Teraz (w pętli) z proporcji obliczamy procenty trafności każdego zapytania, i wyświetlamy dane:
  1. <?php
  2. for($i=0; $i<count($stopnie); $i++)
  3. {
  4.  $proc=floor(($stopnie[$i]*100)/$max);
  5.  // instrukcje wyświetlające
  6. }
  7. ?>


I wyszukiwarka gotowa :-)
:arrow: <b>Przykład</b>
Powyżej można zobaczyć przykład działania wyszukiwarki podpiętej pod phpBB.

<i><b>Metoda działania wyszukiwarki.</b></i>
(na podstawie moich obserwacji)
Trafność zostaje wyliczona w następujący sposób - jest liczona ilosc szukanych słów i podstawiona do ilości ogólnej wyrazów w ciągu i na podstawie tego zostaje zwrócona wartość. Czyli mówiąc prościej - na górze strony wyszukiwania (największa trafność) będą posty z najwyższym stosunkiem wyrazów do szukanego ciągu, czyli np. najkrótsze posty z największą ilością szukanych słów.
Ograniczeniem jest długość ciągu - wyszukiwarka działa dopiero przy szukanych wyrażeniach dłuższych niż 3 znaki.


--------------------

Go to the top of the page
+Quote Post
Wankster
post
Post #2





Grupa: Zarejestrowani
Postów: 208
Pomógł: 0
Dołączył: 19.04.2003

Ostrzeżenie: (0%)
-----


WOW! Dzięki spenalzo! Dzięki bardzo!
Go to the top of the page
+Quote Post
Marusz
post
Post #3





Grupa: Zarejestrowani
Postów: 191
Pomógł: 0
Dołączył: 16.05.2003
Skąd: POLAND

Ostrzeżenie: (0%)
-----


Haha, najbardziej podobał mi się pierwszy post po wpisaniu słowa szukanego: admin smile.gif To tylko taki mały offtopic winksmiley.jpg
Go to the top of the page
+Quote Post
wojto
post
Post #4





Grupa: Zarejestrowani
Postów: 158
Pomógł: 0
Dołączył: 29.06.2003
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


spenalzo dzieki za ta wyszukiwarke, kiedys probowalem zrobic taka.
mam jeszcze pytanie i prosbe, czy dalo by sie tak zrobic (moze juz to jest na tamtej wyszukiwarce), aby zaznaczalo szukany tekst w wynikach, ale chodzi mi o to by sie linki nie psuly.
problem szerzej przedstawilem tutaj


--------------------
Go to the top of the page
+Quote Post
spenalzo
post
Post #5





Grupa: Zarejestrowani
Postów: 2 064
Pomógł: 1
Dołączył: 22.01.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat
Haha, najbardziej podobał mi się pierwszy post po wpisaniu słowa szukanego: admin smile.gif To tylko taki mały offtopic winksmiley.jpg

No cóż... Przykład radosnej twórczości naszego genialnego forumowicza rdpan'a... laugh.gif
A post pokazuje sie, ponieważ został przeniesiony do ukrytego forum, a nie skasowany :-)


--------------------

Go to the top of the page
+Quote Post
sivyer
post
Post #6





Grupa: Zarejestrowani
Postów: 57
Pomógł: 0
Dołączył: 17.04.2002
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Artykul "Using MySQL Full-text Searching" dostępny na stronach http://www.zend.com
Go to the top of the page
+Quote Post
Mnichasso
post
Post #7





Grupa: Zarejestrowani
Postów: 97
Pomógł: 13
Dołączył: 26.06.2003
Skąd: Piekary Śląskie

Ostrzeżenie: (0%)
-----


A można by tak dać opis wyszukiwarki szukającej w plikach ? I żeby była oparta ta wyszukiwarka na plikach ?


--------------------
This is only game
Go to the top of the page
+Quote Post
spenalzo
post
Post #8





Grupa: Zarejestrowani
Postów: 2 064
Pomógł: 1
Dołączył: 22.01.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat
A można by tak dać opis wyszukiwarki szukającej w plikach ? I żeby była oparta ta wyszukiwarka na plikach ?

uuu, tutaj to nie jest takie proste :-)
W tej wyszukwarce co wyżej 99% roboty odwala mysql, a na plikach to musiałbym sam napisać algorytmy, funkcje itd. Ale może kiedyś?


--------------------

Go to the top of the page
+Quote Post
Mnichasso
post
Post #9





Grupa: Zarejestrowani
Postów: 97
Pomógł: 13
Dołączył: 26.06.2003
Skąd: Piekary Śląskie

Ostrzeżenie: (0%)
-----


a dało by sie zrobić wyszukiwarke na mysql która by szukała w plikach txt które mają postać:


[list]1|http://jakiś adres|Nazwa strony|Opis strony|E-mail|1057855002
2|http://jakiś adres|nazwa strony|Opis strony|e-mail|1061981292[list]


--------------------
This is only game
Go to the top of the page
+Quote Post
spenalzo
post
Post #10





Grupa: Zarejestrowani
Postów: 2 064
Pomógł: 1
Dołączył: 22.01.2003
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat
a dało by sie zrobić wyszukiwarke na mysql która by szukała w plikach txt które mają postać:

Jak pliki to nie MySQL.
Z plikami to jest taki problem, że nie da się napisać jednej wyszukiwarki dla każdego rodzaju pliku, ponieważ każdy zapisuje swoje pliki w inny sposób.


--------------------

Go to the top of the page
+Quote Post
msulik
post
Post #11





Grupa: Zarejestrowani
Postów: 83
Pomógł: 0
Dołączył: 31.03.2002
Skąd: Toruń

Ostrzeżenie: (0%)
-----


Może coś zrobiłem nie tak, ale mnie się to nie podoba :|

Po pierwsze:
Cytat
(...) na górze strony wyszukiwania (największa trafność) będą posty z najwyższym stosunkiem wyrazów do szukanego ciągu, czyli np. najkrótsze posty z największą ilością szukanych słów

Hmm... jakoś nie mogę znaleźć sensu takiego kryterium oceniania trafności. <update>Patrz niżej ten post.</update>


Po drugie, po wykonaniu "ALTER TABLE" ponad dwukrotnie wzrosła objętość tabeli (!). Dyskwalifikacja, nie wiem ile zajmuje u Was np. baza phpBB, ale wydaje mi się, że w większysch serwisach - dużo. Pole FULLTEXT staje się bowiem indeksem i kopiuje pole z tekstem każdego rekordu, a więc, jeśli rozpatrywana tabela jest główną tabelą serwisu, to praktycznie objętość bazy wzrasta dwukrotnie.


Zastanawiam się cały czas nad skuteczną wyszukiwarką, np. taką, która opiera się na osobnej tabeli słów kluczowych (relacja {id_słowa, słowo}), generowanych z dodawanych tekstów oraz na relacji {id_słowa, id_tekstu, ilość_wystąpień}. Przy obliczaniu trafności, można połączyć dwa parametry: ilość wystąpień słowa w danym tekście (obliczana jednorazowo przy dodawaniu/edycji tekstu) oraz ilość dopasowanych słów, tzn. ile spośród wpisanych w wyszukiwarce słów, znalazło się w tekście. Nie wiem tylko, jak to połączyć - może sumę "ilości wystąpień"? Albo może średnią z "ilości wystąpień" (tzn. "suma ilości wystąpień" podzielić przez liczbę słów wpisanych w wyszukiwarce)? Tekst z najwyższą średnią (lub sumą, lub innym wyliczonym parametrem) otrzymuje 100%, a następne, odpowiednio mniej. Muszę dokonać obliczeń i wtedy zastanowić się, jaki wzór opracować, może jakaś średnia arytmetyczna ważona czy cuś...

Do tego dochodzi jeszcze ta nieszczęsna odmiana rzeczowników przez przypadki...

Korzyści z fulltextu są nieocenione, ale ten wzrost objętości...

<dodatek date="2003-09-01" time="09:51">
Poza tym nie można podać własnej definicji termu (to określenie pojawia się w teoretycznych opracowaniach dotyczących tego tematu), na przykład term zawierający myślnik zostanie potraktowany jako dwa termy, z których drugi jest termem "zabronionym", czyli takim, który nie może wystąpić w dokumencie.

Poszperałem trochę w sieci i znalazłem kilka prac poświęconych tematowi "ważenia" dokumentów. Już w dokumentaji mysql'a można wyczytać, na czym polega "ważenie" termu kluczowego - im więcej dokumentów, w których ten termu występuje, tym bardziej term traci na wadze. Chodzi o to, żeby wpisując rzadko występujące termy, otrzymać dokument, który zawiera największe jego natężenie. Wzór na wagę termu w dokumencie uwzględnia ilość wystąpień termu w dokumencie ©, ilość dokumentów zawierających term (Dt) oraz ilość wszystkich dokumentów w archiwum (N) i logarytmicznie rośnie wraz ze wzrostem liczby dokumentów w archiwum oraz maleje wraz ze wzrostem liczby dokumentów zawierających term. Ufff winksmiley.jpg
waga_termu_w_dokumencie = C * log (N / Dt)
Tylko nie wiem, dlaczego we wzorze pojawia się logarytm :| Logarytm jest funkcją rosnącą wolniej niż funkcja liniowa. Przy dużych argumentach różnice wartości są niewielkie. Poszperam w sieci jeszcze o tym, może trzeba trochę pogrzebać w statystyce matematycznej angrysmiley.gif
</dodatek>


--------------------
misiu | chór

"Zdeterminowany programista potrafi stworzyć fatalny kod w każdym języku"
Allen Holub
Go to the top of the page
+Quote Post
orson
post
Post #12





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

Ostrzeżenie: (0%)
-----


witam ...

pozwolilem sobie zoptymalizowac ta funkcje ... wg moich testow oraz obserwacji [obie funkcje wywolane w 2 oknach na tej samej bazie ] dzialanie [ zwracane wyniki ] jest identyczne ...
oto poprawiony kod:
[php:1:38f3001feb]<?php
$query = "SELECT MATCH( kolumny full text ) AGAINST (".$_GET['szukane'].") AS stopien, reszta, oddzielona, przecinkami FROM nazwabazy ORDER BY stopien DESC";
$result = mysql_query ($query) or die (mysql_error());
$n=0;
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)){
if($line["stopien"]>0){
$stopnie[]=$line["stopien"];
$proc=round((($stopnie[$n++]*100)/$stopnie[0]),2);
print '
wszystkie kolumny spelniajace kryteria z bazy sa wyswietlane przez $line['nazwa_kolumny']
dodatkowo w zmiennej $proc jest procentowo zawarta wartosc stopnia danego rekordu w porownaniu z rekordem maksymalnym
';
}//*
}

?>[/php:1:38f3001feb]
* gdy bawilem sie ta funkcjia [poprzednia rownierz] zauwazylem [mysql_num_rows();] ze ilosc odebranych wierszy jest wieksza niz ilosc wyswietlonych .... tu mozna wsadzic wyswietlanie rekordow w inny sposob wtedy gdy stopnien = 0 [slowo jest za popularne lub nie znalezione] ale UWAGA po wpisaniu np print " nie znaleziono" ten komunikat zostanie wyswietlony tyle razy ile line['stopien'] > 0 [ dzieki petli while]

teraz moze kilka wyjasnien ...
[php:1:38f3001feb]
$max=$stopnie[@array_search(@max($stopnie),$stopnie)];
?>[/php:1:38f3001feb]
po co questionmark.gif przecierz wyniki zapytania ukladane sa wg stopnia [od najwiekszego do najmniejszego] a maxymalna wartosc jest na pozycji 0 w tabeli stopnie ...
[php:1:38f3001feb]<?php
$proc=floor(($stopnie[$i]*100)/$max);
?>[/php:1:38f3001feb]
mozna wsadzic prosto do petli :
[php:1:38f3001feb]<?php
$proc=round((($stopnie[$n++]*100)/$stopnie[0]),2);
?>[/php:1:38f3001feb] ponaddto stosujac round dos tajemy ladniejsze wyniki np w miejsce 90 z florem mamy 91 z round
funkcja jest mniejsza ... ma mniej tabel [ odpada:
[php:1:38f3001feb]<?php
$stopnie[]=$t["stopien"];
$IDs[]=$t["post_ID"];
$sub[]=$t["post_subject"];
$post[]=$t["post_text"];
?>
[/php:1:38f3001feb]
]
i wszysko jest w 1 petli ... co o tym sadzicie questionmark.gif
wszelkie komentarze mile widziane biggrin.gif:D
cya
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 06:07