Un search mai bun

La unul din clientii la care lucram in acest moment am intalnit cateva chestii noi si interesante. Pentru care a trebuit sa gasim solutii la fel de interesante. Una dintre ele a fost o solutie pentru un search inteligent.

Dar sa o luam cu inceputul. Site-ul este un magazin online de consumabile. Targetul este in proportie de 80% format din distribuitori si clienti fideli care stiu direct codurile consumabilelor de care au nevoie. Acest lucru se reflecta intr-o importanta crescuta a unei cautari care sa returneze rezultate bune deoarece aceasta este metoda prin care 80% din vizitatori vor gasi produse in site-ul cu peste 20 000 de repere.

Problema 1: unde te gasesc?

Sistemele clasice de cautare se bazeaza pe un querry al bazei de date pentru termenii cautatii si returnare rezultatelor in functie de numarul de instante ale cheii de cautare in detaliile produsului.

Care-i buba: pai problema e ca eu pot avea un produs care se numeste TC 42145 si daca un vizitator cauta “TC” si un alt produs care se numeste TR 2343 are in descriere “asemanator cu TC 42145, sau TC 23421″ atunci produsul TR 2343 va fi returnat in rezultate inaintea lui TC 42145. De ce? Pentru ca in descrierea lui apare TC de 2 ori pe cand la primul produs nu apare decat o data in titlu.

In mod evident, asta nu e bine. Atunci un sistem de cautare bun ar trebui sa tina cont de “locul” unde gaseste cheia de cautare. De aici rezulta ca daca eu caut ceva si la un produs acea cheie e in titlu si la altul in descriere ar fi bine sa-l pun primul pe cel care avea cheia in titlu. Dar cum fac asta? Pai simplu se acorda un punctaj pentru fiecare locatie, daca gasesc cuvantul cheie in titlu acord 10 puncte acelui produs, daca il gasesc in descriere acord 3 puncte. La sfarsit adunam punctele si pozitionam rezultatele in functie de punctaj (cel mai mare punctaj = primul - duuhh).

Problema 2: gasesc pe “george”, pe “ion” sau pe “george ion”

Am lamurit ce facem cand se cauta un cuvant. Dar daca vizitatorul, shugubatz cum e el, cauta “TC 421″? In acest caz vom cauta in baza de date dupa sistemul pe punctaje de la primul punct dar pt fiecare din cuvintele din string, adica si pt TC si pt 421, si la sfarsit vom aduna punctajele si vom afisa rezultatele dupa aceeasi regula. Astfel dintre produsele “TC 42345″, “TC 42145″ si “TR 421″: primul va fi “TC 42145″ pentru ca contine atat TC cat si 421 si pe amandoua le contine in titlu apoi va fi “TC 42345″ pentru ca contine primul cuvant din stringul cautat adica “TC” si apoi va fi returnat “TR 421″ pentru ca contine in titlu doar un cuvant din string si acesta e al doilea cuvant din string.

Evident punctajele acordate fiecare locatie trebuie sa fie adaptate fiecarui client in parte deoarece produsele sunt denumite diferit si au altfel detaliile.

In speranta ca am aruncat putina lumina asupra unui sistem care la prima vedere ar trebui sa fie banal astept sa-mi spuneti si alte bube pe care le vedeti la sistemul acesta.

11 Responses to “Un search mai bun”

  1. add Says:

    :) buba ar fi ca ai reinventat roata? ‘match against’ ce avea?

  2. Ionut Says:

    Serifule aberezi. Dar te voi lamuri eu. Nu conteaza ca folosesti “match against” sau “like”. Ideea era sa faci cautarea sa tina cont de locatia in care gaseste nu doar de relevanta gasirii. Adica sa diferentiezi intre cheie gasita in titlu si cheie gasita in vreun detaliu al unui produs sau in numele producatorului sau in numele categoriei sau… . Aici era toata smecheria ca sa ai rezultate relevante.

  3. Dragos Says:

    Pardon daca sunt un pic mai nestiutor, dar cum stii cand bagi date intr-o baza de date care e titlul unui articol, care e pretul si tot asa? Ce design are baza aia de date?

    Ar insemna sa faci tabele nu pe produse, ci pe caracteristici ale produselor si cauti in alea prin niste cueriuri de te doare capul.

    Practic, cand bagi un produs din administrate, titlul se duce intr-o tabela, pretul in alta, descrierea in alta. Pe urma tu cand faci cautarea, cate cueriuri rulezi simultan sa faci cautare simultana in toate tabelele separate?

    S-ar putea sa ne faci varza rezultatele nu?

    S-ar putea sa ma insel totusi…si sa se poata face ce spui tu aici.
    Un demo ai?

  4. Ionut Says:

    cand se lanseaza site-ul promit sa dau link - ca preview - e posibil trebuie doar ca platforma de administrare sau cms cum vrei sa-i spui sa fie destul de desteapta - ajuta daca o faci intern si nu o iei de pe net.

  5. add Says:

    “Nu conteaza ca folosesti “match against” sau “like”.” lol

    ce are match against pe mai multe campuri atunci? daca tot aberez…

    Esti tu convins ca greutatea calculata de tine e mai buna decat cea calculata de oameni care au mai facut ceva SQL la viata lor?

  6. Ionut Says:

    da pt ca tine cont de campul in care se gaseste cuvantul cautat - e relativ logic.

  7. Zero Says:

    Daca am inteles bine vrei ca rezultatul cautarii sa tina cont, pe langa “scoring”-ul textului cautat, si de campul in care acesta se afla. Cu alte cuvine vrei sa ai un indice de prioritate pentru anumite campuri. In cazul asta cred ca interogarea demonstrativa de mai jos should do the trick. Am presupus ca ai un tabel de produse cu id, denumire si descriere. Query-ul va intoarce rezultatele cautarii dupa “$search_text” in campurile denumire si descriere iar rezultatele care contin “$search_text” in denumire (am presupus ca asta e mai important) vor fi afisate primele:

    mysql_query(”SELECT `id`, `denumire`, `descriere`, MATCH(`denumire`) AGAINST (’”.$search_text.”‘) AS `scoring_denumire`, MATCH(`descriere`) AGAINST (’”.$search_text.”‘) AS `scoring_descriere` FROM `produse` WHERE MATCH(`denumire`, `descriere`) AGAINST (’”.$search_text.”‘ IN BOOLEAN MODE) ORDER BY `scoring_denumire`, `scoring_descriere` DESC”, $connection);

    Nu l-am testat insa ar trebui sa functioneze. Daca mai adaugi si operatorii specifici “boolean full-text search” vei avea un motor de cautare destul de cuprinzator.

    Daca a gasit cineva alta solutie, please share :)

  8. Ionuţ Pârvu, mâncând web pe pâine in România » Blog Archive » Importanta unui CMS bun Says:

    […] sa configureze search-ul pentru a se potrivi cat mai bine produselor din site (si aici intervine un post anterior in care am explicat despre search) […]

  9. Ionut Says:

    Solutia ta este buna din punct de vedere al codului. Pentru a o aplica pe platforma de administrare a noastra astfel incat sa permita clientului/noua sa modificam greutate fiecarui detaliu al itemilor din baza de date pentru a se potrivi cat mai bine fiecarui client in parte, mai trebuie putin modificat.
    Dar pentru un site care nu este construit pe o platforma de administrare, pe un site custom este chiar oka.

  10. Worker Says:

    Domnilor, in special Dragos, in primu rand se numeste query sql si “cueriuri”…Aci se vorbeste de un caz particular de a face o anumita chestie…O problema de genu asta nu se rezolva asa…In primu rand tre sa stabilieste de la inceput da vrei sa faci o dezvoltare a bazei de date pe orizontala sau pe verticala si apoi sa stick with it…
    Apoi daca urmeze cele trei forme normale de design de baze de date asta iti va rezolva cea mai mare parte a problemelor de genu asta.
    Iar mai departe e problema search engine-ului daca vrea sa caute dupa coduri de produs si/sau dupa descrierea lor, daca vrea sa parseze descrieri, prin metode sql sau de limbaj de programare adoptat etc…
    Ideea e ca nu poti sa-ti bazezi desig-ul bazei de date doar pe ca sa-ti raspunda unor cazuri particulare…Nu zic ca nu e bine sa nu le ei in consideratie, dar ele nu trebuie sa fie definitorii…si asta ca regula generala in arhiecturi de sisteme…nu doar la nivel database.

  11. Worker Says:

    Asta nu inseamna si nu duce la faptul ca nu mai ai felxibilitate in ati construi baza de date…dar tocmai aci intervine ideea unei baze de date bune …sa fie corect “desenata”, flexibila si sa-ti asigure din start posibilitatea de a-ti raspunde la 80% din probleme…celelalte 20% pot fi reprezentate de chestiuni neprevazute, de schimbari intervenite pe parcusrul procesului de dezvoltare…sunt multe situatii

Leave a Reply