Kirjailija: Ibrahim Diallo
Julkaistu 2. heinäkuuta 2014 ~ 16 minuuttia luettuHaku on tärkeä ominaisuus verkkosivustolla. Kun harvat lukijani haluavat etsiä tiettyä kohtaa blogissani, he käyttävät hakukenttää. Se toimi aiemmin Google-haulla, mutta olen sittemmin vaihtanut sen omaksi kotitekoiseksi versioksi, ei siksi, että osaisin tehdä paremmin, vaan siksi, että se oli mielenkiintoinen haaste.
Jos sinulla on kiire ja haluat vain, että sivustosi on haettavissa, tee se, mitä tein aiemmin, käytä Googlea.
// Search.php-tiedostossa $term = isset($_GET["kysely"])?$_GET["kysely"]: ""; $termi = urlencode($termi); $verkkosivusto = urlencode("www.sivustosi.com"); $redirect = "https://www.google.com/search?q=site%3A($website)+($term)"; header("Sijainti: $uudelleenohjaus"); poistua;
Se, mitä se tekee, on melko yksinkertaista. Hanki käyttäjän välittämä termi ja välitä se Googlen hakusivulle. Rajoita hakutulos nykyiseen verkkotunnukseemme käyttämällä hakukyselyssä avainsanaa site:. Kaikki Googlen indeksoimat sivusi ovat nyt saatavilla haun kautta. Jos kuitenkin haluat hoitaa etsintäsi kotona, jatka lukemista.
Kotitekoinen hakuratkaisuEnnen kuin siirrymme pidemmälle, kokeile käyttää tämän blogin hakukenttää. Se käyttää samaa prosessia, jonka kuvailen alla. Jos sinusta tuntuu, että tämä on mitä haluat, jatka lukemista.
Tämä ratkaisu on tarkoitettu pienille verkkosivustoille. Käytän LIKE-merkkiä, jossa on jokerimerkit molemmissa päissä, eli hakuasi ei voi indeksoida. Tämä tarkoittaa, että ratkaisu toimii hyvin blogissasi tai henkilökohtaisessa verkkosivustossasi, joka ei sisällä tonnia tietoa. Siirrä se suurelle verkkosivustolle ja se voi olla erittäin hidasta, mitä emme tee tässä.
Huomautus: Jos sinulla on 5000 blogitekstiä, olet edelleen kunnossa. .
Otamme tämän blogin rakenteen viitteenä. Jokaisessa blogikirjoituksessa on:
- Otsikko p_title
- URL-osoite p_url
- Yhteenveto p_summary
- Viestin sisältö p_content
- Ja kategoriat kategoria.tunnistenimi
Jokaiselle kenttään, joka vastaa hakutermimme, annamme sille pisteet. Pisteet perustuvat ottelun tärkeyteen:
// tarkat termit vastaavat otsikosta $scoreFullTitle = 6; // vastaa otsikkoa osassa $scoreTitleKeyword = 5; // tarkat termit löytyvät yhteenvedosta $scoreFullSummary = 5; // täsmää yhteenveto osassa $scoreSummaryKeyword = 4; // tarkat termit löytyvät sisällöstä $scoreFullDocument = 4; // täsmää asiakirjan osa $scoreDocumentKeyword = 3; // vastaa luokkaa $scoreCategoryKeyword = 2; // vastaa URL-osoitetta $scoreUrlKeyword = 1;
Ennen kuin aloitamme, on muutamia sanoja, jotka eivät vaikuta paljon hakuun ja jotka pitäisi poistaa. Esimerkki "in","se","a","the","of" ... . Suodatamme ne pois ja voit vapaasti lisätä sanat, jotka eivät ole mielestäsi merkityksellisiä. Toinen asia on, että haluamme rajoittaa kyselymme pituutta. Emme halua, että käyttäjä kirjoittaa romaanin hakukenttään ja kaataa MySQL-palvelimemme.
// Poista tarpeettomat sanat hakutermistä ja palauta ne taulukkofunktiona filterSearchKeys($query)( $query = trim(preg_replace("/(\s+)+/", " ", $query)); $words = array( // laajentaa tätä listaa sanoillasi "hän","minä","me","he","hän","to","mutta","tämä","ne","then"); ", $kysely) $keynä)( if (in_array($key, $list))(jatka; ) $sanat = $avain; if ($c >= 15)( break; ) $c++ ; ) palauttaa $sanat ; ) // rajoittaa sanojen merkkien lukumäärää toiminto limitChars($query, $limit = 200)( return substr($query, 0,$limit); )
Aputoimintomme voivat nyt rajoittaa merkkien määrää ja suodattaa hyödyttömiä sanoja. Tapa, jolla toteutamme algoritmimme, on antaa pisteet aina, kun löydämme osuman. Yhdistämme sanoja käyttämällä if-lausetta ja keräämme pisteitä, kun sovitamme enemmän sanoja. Lopuksi voimme käyttää tätä pistemäärää tulosten lajitteluun
Huomautus: En näytä kuinka muodostaa yhteys MySQL-tietokantaan. Jos sinulla on ongelmia muodostaa tehokas yhteys tietokantaan, suosittelen tämän lukemista.
Annetaan funktiollemme ensin rakenne Huomautus Jätin paikkamerkit, jotta voimme toteuttaa osia erikseen.
Funktiohaku($query)( $query = trim($query); if (mb_strlen($query)===0)( // tyhjää hakua ei tarvita, eikö? return false; ) $query = limitChars($query) ; = array( $docSQL = array(); $urlSQL = array() p_id,p.p_title,p.p_date_published,p. p_url, p.p_summary,p.p_content,p.thumbnail, ((-- Otsikkopisteet ".implode(" + ", $titleSQL).")+ (-- Yhteenveto ".implode(" + ", $sumSQL) .")+ (-- dokumentti ".implode(" + ", $docSQL).")+ (-- tunniste/luokka ".implode(" + ", $ categorySQL).")+ (-- url ". implode(" + ", $urlSQL).")) relevanssina FROM viestistä p WHERE p.status = "julkaistu" ON merkityksellinen >
Kyselyssä kaikki pisteet lasketaan yhteen relevanssimuuttujaksi ja voimme käyttää sitä tulosten lajitteluun.
Vastaa täydellisiä esiintymiäVarmistamme, että meillä on ensin avainsanoja ja lisää sitten kyselymme.
If (count($keywords) > 1)( $titleSQL = "if (p_title LIKE "%".$escQuery."%",($scoreFullTitle),0)"; $sumSQL = "if (p_summary LIKE "%" .$escQuery."%",($scoreFullSummary),0)"; $docSQL = "if (p_content LIKE "%".$escQuery."%",($scoreFullDocument),0)"; )
Nämä ovat ottelut, joilla on korkeammat pisteet. Jos hakutermi vastaa artikkelia, joka sisältää nämä, niillä on paremmat mahdollisuudet näkyä kärjessä.
Vastaavat avainsanatKäymme läpi kaikki avainsanat ja tarkistamme, vastaavatko ne jotakin kenttää. Luokkahakua varten käytin alikyselyä, koska viestillä voi olla useita luokkia.
Foreach($keywords $keynä)( $titleSQL = "if (p_title LIKE "%.DB::escape($key)."%",($scoreTitleKeyword),0)"; $sumSQL = "if (p_summary LIKE "%".DB::escape($key)."%",($scoreSummaryKeyword),0)"; $docSQL = "if (p_content LIKE "%".DB::escape($key)."% " ,($scoreDocumentKeyword),0)"; $urlSQL = "jos (p_url LIKE "%".DB::escape($key)."%",($scoreUrlKeyword),0)"; $categorySQL = "jos ( (SELECT count(category.tag_id) FROM luokasta LIITTY post_category PÄÄLLE post_category.tag_id = category.tag_id WHERE post_category.post_id = p.post_id AND category.name = "".DB::escape($key)."") > 0 ,($scoreCategoryKeyword),0)"; )
Kuten alla oleva kommentoija huomautti, meidän on varmistettava, että nämä muuttujat eivät ole tyhjiä taulukoita tai kysely epäonnistuu.
// Jos se on tyhjä, lisää 0 if (tyhjä($titleSQL))( $titleSQL = 0; ) if (tyhjä($sumSQL))( $sumSQL = 0; ) if (empty($docSQL))( $docSQL = 0; ) if (tyhjä($urlSQL))( $urlSQL = 0; ) if (tyhjä($tagSQL))( $tagSQL = 0; )
Lopussa kyselyt ketjutetaan ja lasketaan yhteen, jotta voidaan määrittää viestin osuvuus hakutermin kannalta.
// Poista tarpeettomat sanat hakutermistä ja palauta ne taulukkofunktiona filterSearchKeys($query)( $query = trim(preg_replace("/(\s+)+/", " ", $query)); $words = array( // laajentaa tätä listaa sanoillasi "hän","minä","me","he","hän","to","mutta","tämä","ne","then"); ", $kysely) $keynä)( if (in_array($key, $list))(jatka; ) $sanat = $avain; if ($c >= 15)( break; ) $c++ ; ) palauttaa $sanat ; ) // rajoittaa sanoja merkkien määrä function limitChars($query, $limit = 200)( return substr($query, 0,$limit); ) function search($query)( $query = trim ($kysely); if (mb_strlen($query)===0)( // ei tarvita tyhjää hakua? return false; ) $query = limitChars($query) // Punnituspisteet $scoreFullTitle = 6 $; scoreFullKeyword = 4; ")+ (-- Yhteenveto ".implode(" + ", $sumSQL).")+ (-- dokumentti ".implode(" + ", $docSQL).")+ (-- tunniste/luokka ".implode" [ relevanssi DESC,p.page_views DESC RAJA 25";
Nyt search.php-tiedostosi voi näyttää tältä:
$term = isset($_GET["kysely"])?$_GET["kysely"]: ""; $hakutulokset = haku($termi); if (!$search_results) ( echo "Ei tuloksia"; exit; ) // Tulosta sivu tulosten kanssa tästä.
Loimme yksinkertaisen hakualgoritmin, joka pystyy käsittelemään kohtuullisen määrän sisältöä. Valitsin mielivaltaisesti pistemäärän jokaiselle ottelulle. Voit vapaasti muokata sitä sinulle parhaiten sopivaksi. Ja aina on parantamisen varaa.
On hyvä idea seurata käyttäjiltäsi tulevaa hakutermiä, jotta näet, etsivätkö useimmat käyttäjät samaa asiaa. Jos kuvio on olemassa, voit tallentaa heille matkan ja tallentaa tulokset välimuistiin käyttämällä Memcachedia.
Jos haluat nähdä tämän hakualgoritmin toiminnassa, siirry eteenpäin ja yritä etsiä artikkelia sivun yläreunassa olevasta hakukentästä. Olen lisännyt lisäominaisuuksia, kuten sen osan palauttamisen, josta tekstissä osuma löytyi. Voit vapaasti lisätä ominaisuuksiasi.
Piditkö tästä artikkelista? Voit tilata lukeaksesi lisää mahtavia.
.Aiheeseen liittyvänä huomautuksena, tässä on joitain mielenkiintoisia artikkeleita.
On aika käsitellä mysql_*-funktioita lopullisesti. Nämä menetelmät ovat vanhentuneita ja hitaita. Päivityksen aika on kulunut kauan, mutta näemme sen edelleen kaikkialla. Koska en voi pakottaa jokaista kirjoittajaa päivittämään opetusohjelmaansa ja blogejaan, päätin kirjoittaa postauksen, jonka toivon paremmaksi ja tarjotakseni olennaiset tiedot uusien tulokkaiden auttamiseksi.
Vim on suosikki tekstieditorini päätteessä. Pelattuani hetken nanolla ja emacsilla, päädyin vihdoin vimiin sen yksinkertaisuuden vuoksi (paljas minulle, kiitos). Vaikka sitä voidaan mukauttaa ja käyttää kuin kokonaista IDE:tä, käytän sitä enimmäkseen tiedostojen muokkaamiseen palvelimillani ja pienten mutta olennaisten muutosten tekemiseen. Älkäämme ryhtykö toimittajasotaan, vaan aloita.
Kommentit (45)Zaryel 12. elokuuta 2015:
Ian Mustafa 26. syyskuuta 2015:
Rob 29. syyskuuta 2015:
adeem 11. helmikuuta 2016:
Ivan Venediktov 9. huhtikuuta 2016.
Päätehtävät:
- toteuttaa haku siten, että hakukyselyn riville syöttämisen jälkeen hakutulokset näkyvät tämän rivin alapuolella
- tulospyyntö tulee tehdä vasta hakukyselyn syöttämisen jälkeen
Okei, mennään!
Itse lohkon likimääräinen asettelu hakurivillä ja div-lempinimellä, johon lisäämme hakutulokset:
Koska Haku on käytettävissä sivuston otsikossa, lisätään vastaavat hakuskriptit ja tulosten tyyli:
//katkaise haku: $APPLICATION->AddHeadScript("/search/ajax_search.js"); $APPLICATION->AddHeadScript("/search/jquery.mCustomScrollbar.js"); $APPLICATION->SetAdditionalCSS(SITE_MALLINE_PATH . "/css/ajax_search.css"); $APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH . "/css/jquery.mCustomScrollbar.min.css");
Katsotaan nyt, mitä ajax_search.js-tiedostossamme on:
Funktio get_result ()( //tyhjennä hakutulokset $("#search_result").html(""); //et ole vielä saaneet hakutuloksia - näytä esilataaja $("#search_result").append(" "); $.ajax(( type: "POST", url: "/search/ajax_search.php", data: "q="+q, dataType: "json", menestys: function(json)( //clear) preloader $("#search_result").html(""); $("#search_result").append("" //lisää jokainen json-taulukon elementti div:n sisään käyttämällä class="live-search" (); asettelu, jota voit käyttää omaasi) $.each(json, function(indeksi, elementti)) ( $("#search_result").find(.live-search").append(""+element.TITLE+""+element. BODY_FORMATED+" "); //console.log (element.BODY_FORMATED)); //tyyli vieritys $(.live-search). 0; var q = ""; $(dokumentti).ready(function() ( $("#q").keyup(function() ( q = this.value; clearTimeout(ajastin); ajastin = setTimeout(get_result, 1000) ); $("#reset_live_search").click(function() ( $("#search_result").html(""); ));
näppäintoimintoa kutsumme get_result()-funktioksi, joka itse asiassa täyttää div-nimen id="search_result" Ajaxissa.
mCustomScrollbar on vain muotoilukutsu (voit poistaa sen käytöstä).
Saamme tiedot osoitteesta /search/ajax_search.php JSON-muodossa.
Kaikki on selvää JS-komponentin kanssa, katsotaan nyt mitä tapahtuu ajax_search.php:ssä:
Tässä tapauksessa haku suoritetaan Bitrix CSearch -luokan hakumenetelmällä. PARAM2:ssa kirjoitetaan, mitä tietolohkoa etsimme. Työnnämme hakutulokset $result-taulukkoon. Huomaa, että $res['ITEM_ID'] voi sisältää joko kohteen tai osion. Riippuen siitä, mitä löysimme, $result_item['BODY_FORMATED'] -kohtaan työnnetään joko osion otsikko tai tekstinpala löydetystä tietolohkoelementistä.
Tämän päivän opetusohjelmassa tarkastellaan php mysql -hakua. Hakukomentosarjoja on valtava valikoima, jotkut käyttävät tietokantaa, toiset tekevät ilman sitä, on tarkennettuja hakuja tarkalla lajittelulla. Keskitymme tavalliseen yksinkertaiseen hakuun, joka etsii tietoa kahdesta taulukosta tietokannasta MySQL.
Ensimmäinen askel. MySQL-tietokanta.
Tietokannan luominen search_lite, siinä on kaksi pöytää uutiset- uutiset ja vac- avoimia työpaikkoja.
Aseta oikeudet:
Kirjaudu sisään - " juuri",
Salasana - "",
Isäntä - " paikallinen isäntä".
Tyhjennä uutistaulukko.
Uutistaulukon taulukkorakenne -- LUO TAULUKO, JOS EI OLE OLEMASSA `news` (`id` int(2) NOT NULL, `title` varchar(255) NOT NULL, `text text NOT NULL, PRIMARY KEY (`id `)) ENGINE=MyISAM OLETUSMERKKI=cp1251;
Kaatopöytä tyhjillään - avoimia työpaikkoja.
Taulukon 'vac' taulukkorakenne -- LUO TAULUKO, JOS EI OLE 'vac' ('id' int(2) NOT NULL AUTO_INCREMENT, 'title' varchar(255) NOT NULL, 'text' text NOT NULL, PRIMARY KEY (` id`)) ENGINE=MyISAM OLETUSMERKKI=cp1251 AUTO_INCREMENT=3 ;
Toinen vaihe. HTML ja PHP.
Yhteyden muodostaminen tietokantaan. Aseta muuttujalle ehto $haku, jossa hakukyselyä ei ole annettu tai se on alle 4 merkkiä pitkä, tarkistamme myös vinoviivat ja katkaisemme muuttujan. Luomme kaksi kyselyä, jotka etsivät kahta taulukkoa tietokannasta uutiset Ja vac hakuehtojen mukaan kenttien mukaan teksti. (Voit jo valita kuinka monta taulukkoa tarvitset hakuun. Sinulla on esimerkiksi taulukoita oppitunteja, materiaaleja, artikkeleita jne. Voit myös muuttaa hakuehtoja kentän sijaan teksti, voit valita kentän otsikko tai muuhun kenttään.) Sitten ilmoitamme kuinka monta merkkiä tekstissä on, kun näytämme haun muuttujassa $symbolit. Jos taulukoissa uutiset Ja vac Haulla ei löytynyt mitään, näytämme viestin. Jos löytyy, näytä tiedot kahdesta taulukosta uutiset Ja vac tietylle hakukyselylle.