1 (edited by zygis 2009-05-12 06:46:32)

Topic: Paieška

Turiu tokią bėdelę: tarkim stulpelyje turiu kažkokį tekstą, ir tarkim zodi kuri reikia rasti. Paprastai pasinaudoji LIKE ir viskas gerai, bet dabar prireikė dar surušiuoti pagal tai, kiek stipriai vienas ar kitas tekstas atitinka ieškomą žodį, t.y. kiek kartų jis pasikartoja... Be viso to dar reikia, kad ieškomas žodis nebūtų kito didesnio žodžio viduryje... žiūrinėjau čia bet grąžinami reikalai tik 1 arba 0, t.y. pasikartojimų neskaičiuoja... Gal minde žinai kokį workaroundą ar kokį funkcijų rinkinį man padėsentį?  Googlis kažkaip nenori kalbėti šia tema...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

Pabandysiu trumpai: paieškos sistemų gamyba yra labai rimtas ir gana sudėtingas procesas. Kuo norima turėti tikslesnius rezultatus, kuo greičiau, iš kuo daugiau duomenų tuo tai kainuos daugiau tiek resursų tiek programavimo laiko.

Jeigu paieška yra paprasta - ok - pasidaryk ją pats, jeigu sudėtinga - gal vertėtų pasinaudoti jau sukurtais paieškos varikliais, tokiais kaip Lucene, Google ir pan.

Kalbant apie konkretų atvejį, praktika rodo, kad geriau iš anksto "sukramtyti" duomenis taip, kad norint atlikti paiešką, nereikėtų daug vargti. Tai mano akimis procesas turėtų būti toks:
a) yra indekso stukrūta, kurioje guli visi žodžiai, ir visi ryšiai su objektais;
b) objekto (šiuo atveju teksto) įkėlimo metu, jis yra skaidomas į žodžius, nauji žodžiai keliami į indeksą, surandami visi esantys, suskaičiuojami kiekiai ir viskas surašomą į indekso-objekto ryšių lentelę;
c) paieška atliekama indekso-ryšių lentelėje (pati paieška indekse, o rikiavimas pagal ryšiuose esančius kiekius kiekvienam objektui);

Tai čia toks kelias gaunamas logiškai mąstant. Kurioje vietoje galima kažką spartinti, karpyti, tobulinti pasimatys realizuojant. Arba pačioje pradžioje vertėtų atlikti eksperimentų/modeliavimų.

čia viską rašiau remdamasis ta patirtimi, kad dažniausiai objektų įkėlimų (INSERT) į sistemą skaičius yra pakankamai mažas lyginant su atliekamų paieškų (.. SELECT) skaičiumi. Tokiais atvejais visą sunkų darbą atliekame įkėlimo metu, tam, kad skaitant viskas būtų labai lengva ir paprasta.

3 (edited by zygis 2009-05-12 21:30:24)

Re: Paieška

Tai jau jo, bandžiausi visokius variantus ir kuo toliau tuo labiau linkstu link vienos lenteles/indekso sudarymo, vistik kol kas pasikartojimų paskaičiavimo atsisakiau, nes nėra tiek laiko nei noro kažką labai milžiniško konstruoti, juolab klientas skūpus :) o dėl google siūliau, bet aišku netiko :D  Any way, dėkui už patarimus, kai kuriuos dar pavirškint reikia.

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

Kaip ir daug problemų išsisprendė naudojant indeksus+view. Viskas lyg ir būtų gerai, bet kylo problemų, kad pasidarau view, atliekami kažkokie tai veiksmai ir jei kitas vartotojas tuo metu prisijungė, tai view perrašė, ir pirmasis galutiniame variante gauna netinkamus rezultatus... Galima generuoti unikalius pavadinimus VIEW'ams, bet tada man rodos labai neoptimalu bus, jei kursiu dropinsiu ir panašiai. Gal yra koks specialus sprendimas tokiam variantui, kad būtų kažkas panašaus į VIEW, bet jis galiotu tik tam vienam prisijungimui... kaip koks variable :) . Nesuranta googlis mano veplenimų, ko aš noriu :)

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

O kaip dažkaip keičiasi informacija, nuo kurios priklauso VIEW'as?

Re: Paieška

beveik nuolat... Ten susideda visas eilutes iš indekso kurios atitinka tam tikrus kriterijus, paieškas ir pan. Pasidarau VIEW , kad nereiktų skriausti mysql'o ir paskaičiuoju iš gautų rezultatų kiek yra pagal skirtingus miestus ir pan, nes keliems filtrams reikia šalia skaičiukų, kiek atitinka eilučių su konkrečia filtro reikšme. Ir kol tai vyksta, daaaug šansų, kad prisijungs kitas vartotojas ir pradės visą ciklą iš naujo... Net pora kartų tai nutiko testuojant dviese...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

Tai kad taip nutiks ir turi nutikti tai čia logiška, dugumoje atveju paieškos rezultatai yra apytiksliai, net ir pas googlą. Tokiose vietose blogai būna tada kai informacija iš duomenų yra šalinama, tada taip, vartotojas gali būt gavęs rezultatus ir poto tie duomenys ištrinami, vartotojas bando pasiekti dokumentus - o jų jau nėra. Kitu atveju jeigu duomenys yra pildomi, bet trinami retai, tai rezultatai tiesiog bus nelabai tikslūs, bet didelės bėdos nebus (-;

O tas dalykas, kad tarp vartotojų veiksmų buvo ištrinti dokumentai tai jis egzistuoja netik paieškoje, bet ir daug kur. Reikia arba informuoti vartotoją apie tai, kad dokumentas buvo katik pašalintas iš sistemos, arba realiai dar turėti tų dokumentų kopijas/backupą/cache'ą.

Re: Paieška

pridedant duomenis jo, nekiltų problemų... bet duomenys keičiasi nuo kelių iki kelių tūkstančių eilučių...
Tai visgi, sprendimas kurti VIEW su unikaliais vardais ir atlikus visus reikiamus veiksmus juos dropinti kiek suprantu nesvarstytinas, pridėjus stulpelį kuris indentifikuotų vartotoją irgi ne koks variantas... nebetektų prasmės pats VIEW. Kaži kokie dar variantai galimi išsisaugoti laikinus duomenis kurie nebereikalingi uždarius susijungimą (dėja mysql'o dar daugelio galimybių nežinau)?.. Su PHP nesinori masyvų prasukinėti, juolab išaugus duomenų kiekimams, neužteks atminties. Dar berašant kilo mintis pasinaudoti InnoDB galimybėmis, bet velgi jei lentelė bus užlockinta, į eilę pradės stoti daug užklausų, kuom tai baigsis - manau aišku... Gal dar pavyks ką išmąstyti pačio mechanizmo viduje, bet taip buvau tuo VIEW susižavėjęs, kad nepastebėjau pagrindinio trūkumo :) ...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

Logiškai mąstant, tai jeigu situacija yra tokia, kad žūt būt vartotojui turi būti parodytas dokumentas, į kurį nuoroda jis dar gavo, bet kol paspaudė ant nuorodos dokumentas buvo ištryntas tai vistik reiktų daryti taip, kad - dokumentas nebūtų trinamas kažkiek laiko, o tik pažymimas, kaip ištrintas ir pašalintas iš indekso. Tuo tarpu, jeigu dar pas kažką yra nuoroda į jį (1 val, 24val. ar pan. laiko) tai jis dar būna pasiekiamas (prie dokumento saugoma ištrinimo data). Realų trinimą atlieka kažkoks background'inis scriptas, kas valandą ar pan.

Re: Paieška

ne ne, ne taip supratai, situacija tokia, kad tai yra įmonių katalogas, pasirenki tarkim kategoriją (viena įmonė turi jų 7, plius reikia kreipti dėmesį į tai kelintoje vietoje ji pažymėta), įvedi dar search stringą, pereinu per indeksą, atsirenku iš kruvos įmonių reikalingas (t.y. pasiimu tik tas kurios atitinka kriterijus) ir iš jų susikonstruoju VIEW kartu paskaiciavęs atitinkamus balus ir pan. Tuomet selectinu VIEW su ORDER BY susirikiaves pagal tam tikrų filtrų reikšmes (tarkim pavadinimas A-Z, arba kai nenurodyta, pagal tuos balus ir pan) pasiimu kažkokį kiekį reikalingų eilučių atvaizdavimui. Tuomet paskaičiuoju kiek iš mano atrinktos krūvos įmonių (VIEW'E) turi miestą Vilnius , Kaunas ir pan. (Labai patogu selectint iš VIEW, nes nebereikia su didžiulėm sąlygom maltis didžiajam indekse), taip pat analogiškai susirenku duomenis filtrams apie įmonių tipą (UAB, AB ir pan.). Po šių veiksmų VIEW'E esantys duomenys tampa nebereikalingi. Idealiu atveju būtų smagu turėti kažką panašaus į VIEW ir žinoti, kad tik tas vartotojas ir naudosis tais duomenimis, o prisijungęs kitas vartotojas turės savo "talpyklą". Toks sprendimas būtų labai geras ir tolimesnėje perspektyvoje, nes tarkim pasirinkus kitą miestą ar kitą puslapį, "talpykloje" esančių duomenų net nereiktų atnaujinti, tai sutaupytų tikrai didelius kiekius resursų. Aišku kyla didelis klausimas, ar taip megindamas "taupyti" neišvaistysiu resursų tai realizuodamas....

Iš tikro čia nebe pirmas kartas kai prireikia kažko panašaus į $_SESSION mysql'e :) nes viską peržiūrėjus tikrai daug dalykų kartojasi, kai kuriuose duomenys išties beveik niekada nesikeičia...

Prieš spausdamas "Patvirtinimas" pasigooglinau truputį ir kažkaip tiesiai ant gero keywordo pataikiau ir manau radau sprendimą: TEMPORARY TABLE, jei ne HEAP tai tada unique per connection. Reiks pabandyti rytoj...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

Laikinos lentos galioja tik tam susijungimui, perkrovus puslapį viskas dingsta (-;

Re: Paieška

tai kol kas tinka, kai reiks saugoti ilgesniam laikui, tada tada connect bus galima pakeisti i pconnect  :)

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

Iškilo dar viena problemėlė, o kaip pasitinkrinti ar lentelė egzisuoja prieš ją selectinant? Standartinės priemonės neparodo TEMPORARY TABLE ... Google irgi nieko gero nepasakė...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

Jeigu IF EXISTS nerodo, tai pradžiai handlink error'us (-; Gausi error'ą, kad tokios lentos nėra - vadinasi nėra.

Re: Paieška

Tai ten pas mane emailina, kai gaunamas erroras. šiandien ryte pasitinkrinęs paštą truputį priguliau :) Bet kiek suprantu sprendimo kažkokio nesukeliant erroro nėra?

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Paieška

zygis wrote:

Tai ten pas mane emailina, kai gaunamas erroras. šiandien ryte pasitinkrinęs paštą truputį priguliau :) Bet kiek suprantu sprendimo kažkokio nesukeliant erroro nėra?

Konkrečiai nežinau, reikia eksperimentuoti skaitant manualą, kaip išsiaiškinti ar tmp lentą jau yra, daug jų neteko naudoti. Gal INFORMATION_SCHEMA padės, gal kokie sesijos kintamieji (-;