Rychlé vyhledávání v databázi
- wallkysek
- Člen | 52
Zdravím,
vytvořil jsem vyhledávač(s nápovědníkem), který prohledává databázi
na základě vstupu. bohužel Nápovědník je opravdu pomalý (1sec delay),
v presenteru mám uložený jeden sloupeček databáze ve kterém vyhledávám
(naplním vždy po startu) a pak PhP funkcí porovnávám řetězce.
(používám k tomu autocomplete). Může mě někdo odkázat na nějaký
lepší řešení? Děkuji
- David Matějka
- Moderator | 6445
mysql LIKE?
pokud je to slozitejsi aplikace, pouzij na vyhledavani i autosuggest elasticsearch nebo solr.
- wallkysek
- Člen | 52
On je možná problém v tom že vyhledávám jednotlivá slova, i když jsem použil LIKE, uložil výsledky do jednoho pole a pak sem použil array_uniqe($array); tak to stále má strašně dlouho odezvu. já sem postnu kódy.
js:
$(function() {
var select_name = "GoogleSearch";
$("#google").autocomplete({
source: function( request, response ) {
$.ajax({
url: "{!$presenter->link('autocomplete')}",
data: {
whichData: select_name,
typedText: request.term
},
success: function( data ) {
response( $.map( data, function( item ) {
return { label: item, value: item }
}));
}
});
},
minLength: 2,
open: function() {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function() {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
});
php:
public function renderAutocomplete($whichData, $typedText = ''){
$data = explode(" ", $typedText);
$tempdata = $this->data[$whichData];
foreach($data as $word){
$word = preg_quote($word, '/');
$tempdata = preg_grep("/$word/i", $tempdata);
}
//$matches = array();
// for($i = 0; $i <= 10 and $i <= count($tempdata); $i++){
// array_push($matches, $tempdata[$i]);
//}
$matches = $tempdata;
//$matches = preg_grep("/$typedText/i", $this->data[$whichData]);
$this->sendResponse(new JsonResponse($matches));
}
v databázi je cca. 8 500 řádků
Editoval wallkysek (30. 8. 2013 15:05)
- wallkysek
- Člen | 52
Tak sem zkoušel a zkoušel a jediný co sem se dozvěděl je, že když nemám ve startup()
$this->zboziRepository = $this->context->zboziRepository;
tak to jede optimální rychlostí, ale jakmile tam ten řádek mám, je to minimálně o tu sekundu pomalejší. jenže když tam ten řádek mít nebudu, tak nemůžu vyhledávat v databázi, nebo se mýlím?
- David Matějka
- Moderator | 6445
to vypada na nejakej problem s pripojenim k databazi. zkus dat do configu misto „localhost“ primo ip – 127.0.0.1
- wallkysek
- Člen | 52
matej21 napsal(a):
to vypada na nejakej problem s pripojenim k databazi. zkus dat do configu misto „localhost“ primo ip – 127.0.0.1
netuším proč ale z 1100ms jsem se díky tomu dostal pod 200ms, tak zkusím pár testů a doplním. Zatím se zeptám proč tomu tak asi je? Každopádně děkuji.
- jiri.pudil
- Nette Blogger | 1032
Windows, že? On se totiž zkouší nejdřív připojit na IPv6 adresu a až potom na IPv4.
- wallkysek
- Člen | 52
Tak jsem poupravil vyhledávání na:
$data = explode(" ", $typedText);
$tempdata = array();
$count = 1;
foreach($data as $word){
$tempdata[$count] = array();
foreach($this->zboziRepository->findAll()->where('nazev LIKE', '%' . $word .'%')->fetchPairs('nazev') as $polozka)
array_push($tempdata[$count], $polozka->nazev);
$count = $count + 1;
}
if (count($data) != 1){
$result = call_user_func_array('array_intersect',$tempdata);
}else{
$result = $tempdata[1];
}
$matches = $result;
$this->sendResponse(new JsonResponse($matches));
kde samotné vyhledání dat trvá maximálně 500ms, ale když se na to dotazuju ajaxem (viz. nahoře) odezva je 1–5 sekund, kde odezva se nezvyšuje s počtem slov/výsledků. Řeším to celý výkend a stále nevím jak todle ošetřit.