O funcție importantă pe site este să căutați după secțiune sau pe întreg site-ul. Acest lucru permite utilizatorului să găsească rapid informațiile de care au nevoie. Cel mai adesea, această problemă este rezolvată cu ajutorul căutării full-text sau a căutării de bază prin expresia LIKE. Căutarea full-text este convenabilă prin faptul că schimbă problema paginilor de clasificare în funcție de relevanța pentru DBMS, vă permite să căutați fraze.
Dar, în același timp, impune anumite restricții, în special, face uz de tabele ca MyISAM, nu caută cuvinte, mai scurte de 4 caractere, creează indici suplimentari. Căutarea prin expresia LIKE este mai puțin convenabilă pentru dezvoltator, deoarece funcționează mai lent, complicând căutarea expresiilor. Un dezavantaj obișnuit al ambelor abordări este imposibilitatea unei căutări morfologice. De exemplu, în catalogul de bunuri există un produs "Buchet de trandafiri galbeni", atunci când căutați "trandafiri roșii", utilizatorul nu va vedea acest produs în rezultate. Și mi-ar plăcea mașinii să înțeleagă puțin limbajul natural. Pentru a rezolva această problemă este ușor pe PHP și phpMorphy ne va ajuta în acest sens. phpMorphy vă permite să rezolvați următoarele sarcini:
- Lemmatizarea (obținerea unei forme normale a unui cuvânt)
- Obținerea tuturor formelor unui cuvânt
- Obținerea informațiilor gramaticale pentru un cuvânt (parte din vorbire, caz, conjugare etc.)
- Modificați forma unui cuvânt în funcție de caracteristicile gramaticale specificate
- Modificați forma unui cuvânt conform unui model dat
Sunt suportate diverse codificări:
- toate single-byte (Windows-1251, iso-8859- *, etc.)
- Codificările Unicode sunt utf-8, utf-16le / be, utf-32, ucs2, ucs4.
Trebuie menționat faptul că utilizarea acestei biblioteci va crea o încărcare suplimentară pe server în timpul inițializării și operării.
Mai întâi, descărcați arhiva bibliotecii și despachetați-o, de exemplu, în dosarul "phpmorphy". Dacă este posibil, directorul este inaccesibil serverului web. Apoi, descărcați dicționarele cu o anumită limbă și codificați-le și despachetați-le în folderul "phpmorphy / dicts" din această bibliotecă. Pentru a inițializa biblioteca, conectați fișierul common.php din dosarul "phpmorphy / src" și setați setările:
Pentru a căuta, vom folosi următoarea abordare: cuvinte în fraza de căutare va avea ca rezultat în forma lor inițială, conținut index de căutare, precum și, ca rezultat, în câteva cuvinte la forma inițială, și în funcție de frecvența de repetiție și localizarea cuvintelor - să-l întrebe în greutate, etc - pentru a căuta tabelul indexează fraza de căutare și clasifică rezultatele în funcție de greutate.
Mai întâi, indexăm conținutul care va fi căutat. În exemplul nostru, căutarea se face prin culorile din catalogul de produse. Produsul are un identificator, un nume, o descriere succintă și completă. Codificarea este UTF-8, collate este utf8_bin. Creați un tabel cu următoarele elemente:
și tabelul în care vor fi stocate indicii:
aici "cuvântul" este cuvântul cheie, "prod_id" este identificatorul produsului, "greutatea" este greutatea cuvântului. Fiecare intrare este caracterizată de o pereche unică de cuvinte-produs.
Apoi, vom lua din baza de date toate înregistrările despre bunuri:
Când lucrați cu biblioteca PhpMorphy, amintiți-vă că termenii din dicționare sunt stocați în majuscule, pentru convenience vom traduce conținutul în majuscule. De asemenea, apariția cuvintelor cu litera "e". alinierea utf8_bin ne garantează nici o eroare legată de unicitatea cheilor din tabelul `prod2search`. din moment ce literele "e" și "e" nu vor fi considerate ca fiind un caracter, totuși va fi incorect dacă cuvintele "VERDE" și "VERDE" sunt indexate separat. Prin urmare, înlocuim litera "e" cu "e". Descrierea detaliată poate conține html-etichete, nu le vom indexa și ar trebui să scăpăm de ele.
Iată scriptul care indexează bunurile și apoi vom da o explicație.
Această expresie regulată sparge conținutul în cuvinte separate. Pentru chirilic, se utilizează modificatorul "u". Trebuie amintit că litera "e" nu se încadrează în domeniul "a-z". Expresia regulată se va ocupa corect de această linie:
Matricea $ word_pma [1] conține o listă de cuvinte individuale.
sub $ morphy, ne referim la o instanță a clasei phpMorphy. $ morphy-> lemmatize () returnează un cuvânt într-un șir sau o serie de cuvinte în forma inițială și returnează o matrice a formularului "Source Word" => Un matrice cu o listă de cuvinte în forma inițială. Metoda lemmatize () compară în mod implicit cuvântul în dicționare, cu un rezultat negativ, încearcă să formeze forma inițială în conformitate cu regulile interne, în cazul în care acest lucru nu reușește, FALSE este returnat în locul matricei. În exemplul nostru, am folosit doar dicționarul rus, dar am ales și cuvinte în limba engleză. Prin urmare, dacă este imposibil să formăm forma inițială, am indexat cuvântul primit:
repetat în cod de mai multe ori pentru că, trebuie să expunem diferite cuvinte de greutate în funcție de locația lor. Pentru cuvintele din titlu, am stabilit greutatea la 3, cuvintele din descrierea scurtă - 2, în întregime - 1. Când repetăm cuvântul, noi îi mărim greutatea.
Ca rezultat, obținem un cuvânt $ pentru un singur produs, care are forma "Word" => "Greutate". Am pus aceste date în tabelul `prod2search`:
Scenariul este încă posibil să se îmbunătățească, de exemplu, pentru a interzice indexarea anumitor prepoziții; indice anumite părți ale discursului, de exemplu, numai substantive și adjective; Pentru a exclude căutarea prin cuvinte care sunt prezente în mai mult de jumătate de înregistrări, de exemplu, cuvântul "descriere" este inclus în descrierea completă a fiecărui produs și căutând acest cuvânt și nu caracterizează în nici un fel un anumit produs.
Acest script vă permite să indexați întregul conținut de la zero și servește doar ca utilitate suplimentară. Într-o aplicație reală, trebuie doar să indexați conținutul textului când adăugați sau editați o înregistrare specifică. Pentru a indexa conținutul, vom folosi scenariul de mai sus, dar pur și simplu nu folosiți buclă și va funcționa cu o singură înregistrare. Când editați, înainte de a introduce indexuri în tabelul `prod2search` sau când ștergeți produse - ștergeți intrările irelevante:
unde $ prod_id este identificatorul elementului care este editat sau șters.
Puteți face unele optimizări. Să presupunem că, în plus față de titlu, o descriere scurtă și completă a produsului are și alte caracteristici și atunci când editează utilizatorul modifică numai prețul. În acest caz, conținutul indexat nu sa schimbat și nu este necesară re-indexarea acestuia. Acest lucru poate fi evitat prin compararea cantitatii de continut indexat inainte si dupa editarea bunurilor. Rezolvați câmpurile indexate într-o singură linie și obțineți hash-ul prin md5 ($ str). Apoi inserați valoarea primită în formular și transferați datele către server, comparați hash-ul înainte și după editare. Dacă se potrivesc hash-urile, atunci conținutul nu sa schimbat și reindexarea nu este necesară.
După ce tot conținutul este indexat și tabelul `prod2search` este umplut cu date, puteți începe implementarea căutării.
Să analizăm interogarea. Găsim înregistrări în tabelul `prod2search`. în care cuvinte din lista de cuvinte din fraza de căutare WHERE `s` .`word` IN (" .implode (",", $ sql) "). Când căutăm mai multe cuvinte, mai multe cuvinte se referă la același produs, astfel încât mărfurile să nu se duplică, rezultatul fiind grupat de grupul de produse GROUP BY `s```prod_id`. În același caz, rezumăm greutatea cuvintelor găsite pentru un produs SUM ("greutate") AS "weight_sum". De exemplu, căutăm "trandafiri roșii" - pentru un produs care are ambele cuvinte găsite în descriere, greutatea va fi mai mare decât cea a unui produs cu un singur cuvânt. Rezultatele eșantionului sunt ordonate după relevanță, adică, greutatea ORDER BY by weight_sum DESC. Pentru atunci când căutați mai multe cuvinte într-un rezultat avem doar acele bunuri, descrierea care sunt toate prinse în cuvinte de interogare, considerăm cât de multe cuvinte pentru găsit COUNT ( `s`.`prod_id`) num` AS` și stabilește condiții de aceleași produse CU "num" = ".count ($ sql)". În acest caz, realizate logice „și“ Cuvinte care leagă într-o expresie de căutare, pentru logică „SAU“ condiția de a fi ratat. Ca rezultat, obținem o listă de identificatori de produse care se încadrează în criteriile de căutare. Pentru claritate, înregistrarea cu bunurile pe care le ia o interogare imbricate, dar, în practică, probabil, cea mai bună soluție este de a lua o listă de produse pentru cereri individuale de ID-urile lor. Varianta de interogare cu logică "OR" și limite va funcționa mult mai rapid.
Astfel, cu exemplul catalogului de culori, am implementat o căutare morfologică în limba rusă folosind PHP, MySQL și PhpMorphy. Această metodă poate fi aplicată oricărei părți a site-ului dvs. și va aduce vizitatorul și dvs. mai aproape, doar oferindu-i utilizatorului informațiile pe care le căuta.