Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Prosta wyszukiwarka a jednak problem
Forum PHP.pl > Forum > PHP
kilinho
Witam.

Mam sobie wyszukiwarke osob ktore zarejestrowaly sie na mojej stronie.
Tabela danych tych osob:
ID | Imie | Nazwisko | Miejscowsc | itd

I teraz problem polega na tym ze wpisujac w formularzu znajdz np. Jan Kowalski, to skrypt pyta sie w do tabelki:
select * from tabelka where nazwisko like '%Jan Kowalski%' and imie like '%Jan Kowalski%'
to zapytanie da 0 wynikow.
Jan Kowalski jest wpisywane w jednym polu.
W jaki sposob zadac pytanie badz przerobic skrypt php aby dojsc do takiej formy:
select * from tabelka where nazwisko like '%Kowalski%' and imie like '%Jan%'?
Czy tworzac indeksy w tabelce dla Imie i Nazwisko badz explod`ujac Jana Kowalskiego na dwa oddzielne wyrazy (tworzac z niego tablice i najpierw przeszukac Jan a potem Kowalski). Czy te dwie metody dadza rozwiazanie? (tablica moze byc malo wydajna przy wiekrzej ilosc slow?)
milupo2nd
jeśli zawsze ktos bedzie szukal w formie [imie]_[nazwisko] to rozbij ten ciag na dwa stringi i daj zapytanie:
select * from tabelka where nazwisko like '%[nazwisko]%' and imie like '%[imie]%'
nithajasz
Najlepiej przerób formularz na oddzielne pola imie i nazwisko, a dlaczego? Bo explode utrudni Ci tylko zadanie w przypadku gdy np. ktoś będzie miał dwa imiona i ktoś będzie w ten sposób wyszukiwał albo ktoś będzie miał nazwisko dwuczłonowe.
kilinho
No to w jaki sposob jest zrobiona wyszukiwarka osob np. w najpopularniejszym serwisie przyjaciol szkolnych. Wpisujemy w wyszukiwarce np. Jan Kowalski badz Kowalski Jan to zawsze otrzymamy ten sam wynik. Więc jednak da sie to jakos zrobic. Najprawdopodobniej kazde slowo jest przeszukiwane oddzielnie, tylko ze jakos to musieli fajnie zrobic ze tak szybko dziala. Bo tak ponaszemu jak tu piszemy to kazde slowo bedzie przeszukiwane oddzielne:
imie like '%jan%' and nazwisko like '%jan%' and imie like '%kowalski%' and nazwisko like '%kowalski%'
. To jest dobre rozwiazanie jak mamy mala baze, a jezeli bedziemy mieli jakies 100 000 danych do przeszukania, to ten skrypt bedzie dzialal i dzialal.
Prosze o pomoc
wlamywacz
Bo tam nie używają LIKE gdyż to zabija bazę.
kilinho
Mozna dokladniej, tworza indeksy dla tabeli?
wlamywacz
Na takie tematy to na PHP Pro
Temat: wyszukiwarka
bim2
Bo po co dawać like? Jan to Jan... Nie chce żeby mi znalazło Janosik, albo Wonajan (nazwisko powiedzmy).

WHERE nazwisko = 'Jan' OR imie = 'Jan' OR nazwisko = 'Kowalski' OR imie = 'Kowalski'
wlamywacz
Źle
  1. WHERE nazwisko = 'Jan' OR imie = 'Jan' OR nazwisko = 'Kowalski' OR imie = 'Kowalski'


  1. WHERE imie = 'Jan' AND nazwisko = 'Kowalski' OR imie = 'Kowalski' AND nazwisko = 'Jan'


Jednak nie jest to zbyt praktyczne.
kilinho
Skrypcik generujacy zapytanie do bazy:
  1. <?php
  2. $_GET[query]='Jan Kowalski';
  3.  $szukane_slowa = explode(" ", $_GET[query]);
  4.  
  5.  
  6.  $licz = count($szukane_slowa);
  7.  $query = "SELECT * FROM `uzytkownicy` where"; 
  8.  
  9.  for ($x=0; $x < $licz; $x++){
  10.  $imie[$x] = "`first_name` = '$szukane_slowa[$x]'";
  11.  $nazwisko[$x] = "`last_name` = '$szukane_slowa[$x]'";
  12.  }
  13.  
  14.  
  15.  for ($x=0; $x < $licz; $x++){
  16.  $query .= ' '.$imie[$x].' and '.$nazwisko[($licz-$x-1)].' '; 
  17.  if ($x >= 0 and $x < ($licz-1)){
  18.  $query .= "or";
  19.  }
  20.  }
  21.  
  22.  $znajdz = mysql_query($query);
  23.  while ($znajdz_row = mysql_fetch_array($znajdz)){
  24.  echo $znajdz_row[first_name].' '.$znajdz_row[last_name].'';
  25.  }
  26. ?>

Wygeneruje nam zapytanie po wpisaniu w wyszukiwarce np: Jan Kowalski


  1. <?php
  2. SELECT * FROM `uzytkownicy` where `first_name` = 'Jan' and `last_name` = 'Kowalski' or `first_name` = 'Kowalski' and `last_name` = 'Jan';
  3. ?>


Czy to ma sens?
bim2
Ma. Nie powiem troche to zagmatwałeś. Mogłeś odrazu dać budowe zapytania.
  1. <?php
  2. $szukane_slowa = explode(" ", $_GET[query]);
  3. foreach($szukane_slowa AS $i => $value)
  4. {
  5.  $wheres[] = ' `last_name`=''.$value.'' AND `first_name`=''.$szukane_slowa[$i++].''';
  6. }
  7.  
  8. $sql = 'SELECT * FROM `uzytkownicy` where '.implode('OR', $wheres);
  9. ?>


EDIT: Poprawiłem. Chyba bedzie ok.
kilinho
EDIT: teraz jest tak:
ten skrypt da nam teraz
  1. <?php
  2. SELECT * FROM `uzytkownicy` where `last_name`='Jan' AND `first_name`='Jan'OR `last_name`='Kowalski' AND `first_name`='Kowalski'
  3. ?>

a powinno byc

  1. <?php
  2. SELECT * FROM `uzytkownicy` where (`first_name` = 'Jan' and `last_name` = 'Kowalski') or (`first_name` = 'Kowalski' and `last_name` = 'Jan');
  3. ?>


Pisanie takich skryptow jest zlym rozwiazaniem:
1. Wpisujac Jan to bedzie szukac imie=jan i nazwisko=jan wiec jest bez sensu
2. przy trzech slowach juz trzeba sprawdzac wszystkie kombinacje
3. malo wydajne pzy wiekrzej ilosci danych
4. generowane zapytanie staje sie zbyt dlugie co juz samo spowolni dzialanie

Wniosek:
Szukac innego rozwiazania, byc moze ktos ma jakis pomysł?
bim2
Jak nie wydajne? Maksymalnie ktoś wpisze 3 wyrazy...

Poprawiony:
  1. <?php
  2. $szuakne_slowa = 'lol bim tata';
  3. $szukane_slowa = explode(" ", $szuakne_slowa);
  4. foreach($szukane_slowa AS $i => $value)
  5. {
  6. $tmp = (!isset($szukane_slowa[$i+1])?$szukane_slowa[0]:$szukane_slowa[$i+1]);
  7.  $wheres[] = ' (`last_name`=''.$value.'' AND `first_name`=''.$tmp.'') ';
  8.  $wheres[] = ' (`last_name`=''.$tmp.'' AND `first_name`=''.$value.'') ';
  9. }
  10.  
  11. $sql = 'SELECT * FROM `uzytkownicy` where '.implode('OR', $wheres);
  12. echo $sql;
  13. ?>

Działa ładnie i jest wydajne moim zdaniem.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.