ugrás a tartalomhoz

Google kereső működése?

H.Z. v2 · 2012. Már. 12. (H), 11.11
Azon töröm a fejem, hogy létezik-e hatékony, PHP-ben előállítható megoldás arra, amit a google keresője művel: minden beírt karakter után feldobja a lehetséges találatokat.
Ezt jelen ismereteim birtokában valami ajaxos megoldással tudnám elképzelni, de... ez azt jelentené, hogy minden bill. leütéskor bemegy egy kérés a szerverre, ott megnyílik egy adatbázis kapcsolat, lekéri a lehetséges találatok listáját, majd visszaküldi a böngészőbe.
Hát ez így nem túl hatékony...
OK, valamivel jobb lehetne, ha bevezetnék egy cache-t a szerver oldalon és az első karakter érkezésekor kigyűjteném az összes találatokat, majd a cache-ből válogatnék, de annak meg olyan memória igénye lenne, hogy amiatt halna el az egész. Ha pedig nem memóriába pakolom a cache-t, akkor meg szinte felesleges, hiszen minimum fájlokat kell nyitogatni karakterenként, ami ugyan gyorsabb, mint egy adatbázis kapcsolat felépítése, de még mindig lassú.

Gondolom, valami alapvető technológiai ismeret hiányzik, de nem igazán tudom, mit keressek.
(félreértéseket kerülendő: nem akarok új google-t írni, csak elméleti szinten, nagy vonalakban érdekelne)
 
1

Hát ez így nem túl

kuka · 2012. Már. 12. (H), 11.47
Hát ez így nem túl hatékony...
Szerintem nem olyan vészes.

Egyetlen lehetőséget látok a felsorolt lépések csökkentésére, olyan adatbázis szervert használni amely HTTP kapcsolaton keresztül közvetlenül lekérdezhető és JSON formátumban adja vissza az eredményeket. Mivel ezzel szó szerint nyilvánossá teszed az adatbázist illetve mivel csak NoSQL adatbázisok esetében hallottam ilyen elérhetőségről, 2 adatbázisod kellene legyen:
  • a korlátozott elérésű, amelyben a féltett adatok vannak
  • a nyilvánosan elérhető NoSQL, amelyben kizárólag az autocomplete-el is elérhető adatok vannak
Ebből adódna egy kis plusz munka a két adatbázis összhangban tartásával.

Ami a NoSQL adatbázist illeti, konkrétan az Apache CouchDB-re gondoltam.
2

Köszi

H.Z. v2 · 2012. Már. 12. (H), 12.17
Kicsit továbbgondolva a témát, végül is PHP-ben is lehet démon jellegű programokat írni, csak ha PHP-ben gondolkodom, akkor elsősorban az ingyenes tárhelyeken elérhető szolgáltatások lehetőségeivel gondolkodom. Holott megoldható lenne egy olyan programot írni (akár PHP-ben, akár bármi másban), ami egyszer kapcsolódik az adatbázishoz, majd akár unix socketen át kommunikálva a web szerverrel, kéregeti le a szükséges adatokat az adatbázisból anélkül, hogy sok erőforrást pazarolna a kapcsolódással, fájl megnyitással stb.
Csak annyi a gond, hogy ehhez mindenképpen saját szervert kell üzemeltetni, minimum egy VPS kell hozzá.
----
Két adatbázissal egy nagy gondom van: konzisztencia... Üzemeltetési szempontból egy agyrém.
3

Holott megoldható lenne egy

kuka · 2012. Már. 12. (H), 12.44
Holott megoldható lenne egy olyan programot írni (akár PHP-ben, akár bármi másban), ami egyszer kapcsolódik az adatbázishoz
Persistent Database Connections? Jó kérdés, hogy mysql_pconnect() korlátozva van-e ingyenes szolgáltatóknál.
8

atw, uw, freebase...

Arnold Layne · 2012. Már. 13. (K), 01.33
Megnéztem atw-n, uw-n és freebase-n. Nincs letiltva. Több most nem jut eszembe.
9

Kivágnak

janoszen · 2012. Már. 13. (K), 10.56
Csak ne lepődj meg, ha kivágnak érte. Ez az egyik leggaládabb dolog, amit osztott tárhely szolgáltatóval tudsz csinálni. Ha csak 10-20 user csinálja már felzabálják a max kapcsolatok jó részét.
10

Nem biztos... :)

H.Z. v2 · 2012. Már. 13. (K), 11.44
Már nem emlékszem, melyik szolgáltatónál láttam: a perzisztens kapcsolatokat kezdeményező hívások is át voltak irányítva a hagyományosra. Szóval hiába hívtad a perzisztens verziót, a lap végén ugyanúgy eldobálta mindet.
5

bootstrap

Poetro · 2012. Már. 12. (H), 14.22
A PHP alkalmazásokkal általában az a probléma, hogy lassú a bootstrap és sok memóriát esznek. Ezért ilyen AJAX kiszolgálásokhoz egy minimális PHP-t kell csinálni, és keresési eredményeket erősen kell cachelni, hogy gyorsak legyenek. Azt is csinálhatod, ha mondjuk 100-500ms-ig a felhasználó nem gépel semmit, akkor elküldöd a kérést a szervernek, majd az visszatér egy idő után egy eredményhalmazzal. Ha a kérés után a felhasználó még gépelt valamit pluszban, akkor kliens oldalon még csinálsz az eredményhalmazon egy szűrést a válaszon. Ha ugyanakkor törölt valamit, akkor pedig megjeleníted azokat, amiket válaszul kaptál, és megfelelnek a keresési feltételnek, majd megint indítasz egy kérést a szerverhez, amivel majd szintén bővíted az eredményhalmazodat stb. Érdemes a kliens oldalán is cachelni, akár localStorage-ba, akár csak változóba, hogy a további keresések gyorsabbak legyenek.
Amint látszik itt a kliens oldalon is elég sok logika van, úgyhogy talán érdemesebb egy erre kidolgozott kész megoldást választani. jQuery esetén van erre az autocomplete plugin, de biztosan vannak masszívabb kliens oldali megvalósítások is.
6

Köszi!

H.Z. v2 · 2012. Már. 12. (H), 21.12
Köszi szépen, eszerint jól sejtettem, hogy annyira azért nem triviális a dolog. :)
12

kuka javaslatát

prom3theus · 2012. Már. 14. (Sze), 13.44
kuka javaslatát továbbgondolva pár dolog, ami eszembe jutott:
1.) Ha a CouchDB nem telepíthető a célkörnyezetre, akkor azt javaslom, használj helyette SQLite-ot és írj a lekérések átadásához egy totál primitív gateway-t PHP-ben. Az SQLite-tal egy hagyományos DB-hez képest mindenképp fogsz időtnyerni, mivel hálózatot nem igényel, ugyanakkor hatékonyabb mint egy TXT/CSV állományban turizás mert lehet vele indexelni. A PHP-SQLite gateway-ed összes feladata pedig kimerülne abbam hogy a GET/POST-ban kapott SQL lekérést megfuttatja és JSON-ban visszaadja a visszatérést vagy a hibakódot (erre javasolt struktúra: {success:true/false, data: null/array[objects], errmsg: string} - success true esetén data tartalmazza a resultset-et, success false esetén errmsg a hibaüzenetet). A két adatbázist persze így sem úsznád meg.
2.) Keresési gyakoriságot count-old minden kereshető tétel esetén, erre rendezzél az első karakter leütésekor és add vissza az összes lehetséges találatok mondjuk 20%-át (tehát 100 lehetséges találat esetén az első 20-at). A további leütések esetén elsőként a visszaadott listából próbáljon találatot felszedni a JS, így elképzelhető, hogy sikerül további AJAX kéréseket spórolni. Ezen a gondolatmeneten tovább lehet menni egyéb intelligens(-nek mondható) optimalizálási trükkökön is, például ha egy keresett kifejezés levenshtein távolsága nagyon kicsi egy gyakrabban használt kifejezéshez képest, akkor a már létező, ahhoz hasonló de gyakori kifejezést adja vissza. Ezt mondjuk egész szavak határán van értelme használni (tehát nem [a-z; 1-9] karakterek bevitele esetén, azaz szóhatáron). Ha aztán a felhasználó mégsem a feldobott tooltip-et akarja használni, akkor a keresett kifejezés bekerülhet az adatbázisba (vagy kaphat +1 count-ot a használat gyakoriságára).

Csak ötleteltem.

(Ja és: előny, ha a szerveren fut mondjuk APC, csökkenni fog a PHP bootstrap ideje [amit mondjuk bootstrap csökkentés esetén érdemes megtenni: session_autostart kikapcs, ha van gpc_magic_quotes akkor kikapcs, INI beállítást ha megoldható felülírni hogy semmit ne include-oljon automatice, stb])
4

Sok, nagyon sok adat esetén

Kubi · 2012. Már. 12. (H), 12.44
Sok, nagyon sok adat esetén és nagyon sok keresés esetén, én node.js -el oldanám meg a dolgot szerver oldalon, és nem php-val.

Kezelhető mennyiségű adatnál, ajaxos autocomplete mezőnél én erre olyan megoldást láttam, hogy 2-3 begépelt karakter után adja vissza a találatot, de ekkor az összeset (pl: LIKE 'ABC%'), ez helyzettől függően lecsökkenti a találati listát pár száz elemre, amit gond nélkül át lehet küldeni ajaxon json-el. Plusz karakterek beírásánál ezt a listát csökkenti az autocompleter.
7

OK, de én épp azon méláztam,

H.Z. v2 · 2012. Már. 12. (H), 21.13
OK, de én épp azon méláztam, hogy vajon egy PHP-s rendszeren mindez megoldható-e egyáltalán. ;)
11

Apache Solr

kirunews · 2012. Már. 14. (Sze), 12.08
Egy megoldás: Apache Solr használata. Ilyen jellegű feladatok megoldására van tervezve. Ez egy javás alkalmazás, a PHP-ból URL-ek segítségével tudod meghívni (van hozzá PHP könyvtár is, ha kellene). Az adatbázist először le kell indexelni, amit lehet közvetlen módon (keress rá a Solr dokumentációban arra, hogy 'DIH' - Data Import Handler), vagy saját kóddal meghatározhatod, hogy mit indexeljen.