Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Sugerowanie
piernik
post
Post #1





Grupa: Zarejestrowani
Postów: 65
Pomógł: 0
Dołączył: 9.07.2004

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


potrzebuję stworzyć jakiś mechanizm wyszukiwania podobnych fraz
Mam bazę z powiedzmy 30 tys różnych fraz.
Wpisuję jakąś fraze w pole input np naprawa samochodów i system powinien wyszukać w tych frazach podobne frazy z tym że najbardziej podobne będą na samym początku czyli wynik mógłby wyglądać np tak:

samochodowa naprawa
naprawy samochodów
naprawa samochodowa
naprawa aut
remont samochodów
itd

Jak takie coś zrobić? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
na razie mam tak:
ucinam z frazy szukanej końcówki i dzielę na wyrazy i szukam w bazie 'słowo%'

Później przelatuję przez wszystkie wyniki i sortuję w php na takiej zasadzie:
dzielę frazę szukana i znalezioną na słowa i przelatuję przez wszystkie kombinacje levensteinem - wyniki sumuję i fraza z najniższym wynikiem levensteina trafia na początek.

Nie sprawdza się to przy powyżej 3 wyrazach.
Jak usprawnić takie sortowanie?
Go to the top of the page
+Quote Post
Landon
post
Post #2





Grupa: Zarejestrowani
Postów: 83
Pomógł: 3
Dołączył: 21.04.2007
Skąd: Sosnowiec

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


Pomysłem na pewno będzie

  1. <?php
  2. function podobne($slowo) {
  3. $licz = ($licz) ? $licz : strlen($slowo);
  4. if ($licz > 2 && substr($slowo,0,7) != "http://" && substr($slowo,0,4) != "www.") {
  5. $shortest = -1;
  6. $query = mysql_query("SELECT * FROM {{table}}", "keywords");
  7. while($row = mysql_fetch_array($query)) {
  8. $lev = levenshtein($slowo, $row['name']);
  9. if ($lev == 0) {
  10. $closest = $row['name'];
  11. $shortest = 0;
  12. break;
  13. }
  14. if ($lev <= $shortest || $shortest < 0) {
  15. $closest = $row['name'];
  16. $shortest = $lev;
  17. }
  18. }
  19. $return = ($shortest != 0) ? 'Czy chodziło Ci o: <a href="?q='.$closest.'">'.$closest.'</a>' : '';
  20. }
  21. return $return.'<br>';
  22. }
  23. ?>


Jeżeli słowo nie ma więcej niż 2 litery porównuje je z istniejącymi w bazie.. Mam to w wyszukiwarce ale sa błędy np jak mam w bazie Google a wpisze google to proponuje porównać... A moim zdaniem powinno taki przypadek olać (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)

Edit:

Dobra rozwiązanie teraz porównuje

  1. <?php
  2. function podobne($slowo) {
  3. $licz = ($licz) ? $licz : strlen($slowo);
  4. if ($licz > 2 && substr($slowo,0,7) != "http://" && substr($slowo,0,4) != "www.") {
  5. $shortest = -1;
  6. $query = mysql_query("SELECT * FROM {{table}}", "keywords");
  7. while($row = mysql_fetch_array($query)) {
  8. $lev = levenshtein($slowo, $row['name']);
  9. if ($lev == 0) {
  10. $closest = $row['name'];
  11. $shortest = 0;
  12. break;
  13. }
  14. if ($lev <= $shortest || $shortest < 0) {
  15. $closest = $row['name'];
  16. $shortest = $lev;
  17. }
  18. }
  19. if (strtoupper(slowo) != strtoupper($closest)) 
  20. $return = ($shortest != 0) ? 'Czy chodziło Ci o: <a href="?q='.$closest.'">'.$closest.'</a>' : '';
  21. }
  22. return $return.'<br>';
  23. }
  24. ?>


Umie ktoś lepiej to rozwiązać?

Trochę jest tu:
http://pl.php.net/levenshtein
http://pl.php.net/similar-text

Ten post edytował Landon 11.05.2008, 17:25:24
Go to the top of the page
+Quote Post
merk
post
Post #3





Grupa: Zarejestrowani
Postów: 30
Pomógł: 7
Dołączył: 31.05.2006

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


Być może to będzie pomocne:
http://dev.mysql.com/doc/refman/5.0/en/ful...l-language.html
Go to the top of the page
+Quote Post
guitarnet.pl
post
Post #4





Grupa: Zarejestrowani
Postów: 74
Pomógł: 4
Dołączył: 7.03.2008

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


po pierwsze 30 tys wpisow i takie sugestie to nie jest dobry pomysl... szczerze mowiac fatalny, wyobrazcie sobie obciazenie serwera mysql takimi zapytaniami

co ja zrobilem to cachowanie w sesji wpisanego wzoru szukania czyli jak ktos wpisze w jednej sesji jakis wyraz zostanie on zapamietany i przywolany przy powtorzneiu, dodatkowo wyniki wyszukiwania i wpisany wzor zapamietywane sa w osobnej tabeli ktora jest przeszukiwana w pierwszej kolejnosci

oczywiscie nalezy oszacowac czy taka tabela ma sens pod katem wystepowania powtorzen, w moim przypadku mam duzo wiec ma sens wysylac dodatkowe szybkie zapytania zamiast szukac w duzej bazie

spotkalem sie rowniez z rozwiazaniem opartym na dodatkowej specjalnie generowanej tabeli z indeksami z 2 polami keyword-wyniki ktora jest przeszukiwana zamiast prawidlowej z 30tys , taka skrotowa tabela
nalezaloby oczywiscie sprawdzic czy i jesli wystepuje oszczednosc operacji i czasu odwolania, w tej tabeli odswizanej np co 24 godz znajduja sie, nigdy nie mialem czasu tego wdrozyc ale na oko widac ze w moim systemie to lepsze i szybsze rozwiazanie niz cache na sesjach i podwojne sprawdzanie cachu
Go to the top of the page
+Quote Post
Landon
post
Post #5





Grupa: Zarejestrowani
Postów: 83
Pomógł: 3
Dołączył: 21.04.2007
Skąd: Sosnowiec

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


wydaje mi sie że to powinno się przydać, no ale ma podobno problemy z pl znakami...

http://dev.mysql.com/doc/refman/5.0/en/str...unction_soundex

  1. <?php
  2. function podobne($slowo) {
  3. $licz = ($licz) ? $licz : strlen($slowo);
  4. if ($licz > 2 && substr($slowo,0,7) != "http://" && substr($slowo,0,4) != "www.") {
  5. $shortest = -1;
  6. $query = mysql_query("SELECT * FROM keywords WHERE SOUNDEX(UPPER('".$slowo."')) = SOUNDEX(UPPER(name)) ");
  7. while($row = mysql_fetch_array($query)) {
  8. $lev = levenshtein($slowo, $row['name']);
  9. if ($lev == 0) {
  10. $closest = $row['name'];
  11. $shortest = 0;
  12. break;
  13. }
  14. if ($lev <= $shortest || $shortest < 0) {
  15. $closest = $row['name'];
  16. $shortest = $lev;
  17. }
  18. }
  19. if (strtoupper(slowo) != strtoupper($closest)) 
  20. $return = ($shortest != 0) ? 'Czy chodziło Ci o: <a href="?q='.$closest.'">'.$closest.'</a>' : '';
  21. }
  22. return $return.'<br>';
  23. }
  24. ?>


tylko baza musi być w utf8_polish_ci wtedy niema problemów (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

No ale np nie wyświetla dla sciana nie wyświetli ściana trzeba samemu to dopisać (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
czyli REPLACE('cos w co', 'co', 'naco')

3

Ten post edytował Landon 12.05.2008, 19:04:17
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 22.08.2025 - 17:02