Søke etter poster er et vanlig krav i webapplikasjoner. Det er vanligvis et krav om at brukerne raskt får tilgang til dataene de vil ha fra store poster. Mens det er mulig å gjøre dette ved hjelp av enkle SQL-spørringer, er det noen ganger mer effektivt å bruke en søkemotor.
Solr er en populær søkeplattform fra Apache Lucene-prosjektet. De viktigste funksjonene inkluderer kraftig fulltekstsøk, treffutheving, fasettert søk, nær sanntidsindeksering, dynamisk clustering, databaseintegrasjon, rik dokumenthåndtering og geospatial søk. I denne opplæringen ser vi på å utføre fulltekstssøk ved hjelp av Sunspot, som er et bibliotek som muliggjør integrasjon av Solr i rubinapplikasjoner.
Jeg har laget en enkel app på Github som jeg skal bruke her i stedet for å starte med et nytt prosjekt. Appen viser en liste over produkter med navn, bilde, pris og beskrivelse. Jeg har tatt med noen frødata slik at du kan kjøre rake db: frø
hvis du ikke vil skrive inn dataene selv. Programmet bruker Paperclip for bildevedlegg, og siden jeg bruker bildeopppasning, må ImageMagick installeres på systemet ditt. Du vil også kreve at Java-kjøretiden er installert på maskinen din for å fortsette med opplæringen.
Bildet nedenfor viser søknaden. Søkeformularen øverst gjør ingenting for øyeblikket, men vi vil gjøre det mulig for en bruker å søke gjennom produktene og få resultater basert på ikke bare produktnavnet, men også på beskrivelsen.
Vi starter med å inkludere Sunspot og Solr perler i vår Gemfile. For utvikling, bruker vi sunspot_solr
perle som følger med en ferdigpakket Solr-distribusjon, derfor trenger vi ikke å installere den separat.
perle 'sunspot_rails' gruppe: utvikling gjør perle 'sunspot_solr' ende
Løpe bunt installasjon
og kjør deretter følgende kommando for å generere Sunspot-konfigurasjonsfilen.
skinner generere sunspot_rails: installere
Dette skaper /config/sunspot.yml
fil som lar appen din vite hvor du skal finne Solr-serveren.
For å sette opp objektene du vil indeksere, legg til en søkbar blokk til objektene. I startprosjektet har vi en produktmodell med navn, pris, beskrivelse og fotofelt. Vi vil aktivere et fulltekstsøk som skal gjøres på navn og beskrivelse felt. I /models/product.rb
Legg til:
søkbar gjør tekst: navn,: beskrivelse slutten
Start Solr-serveren ved å kjøre:
rake solflekk: solr: start
Sunspot indekserer nye poster som du oppretter, men hvis du allerede har noen poster i databasen, kjør rake sunspot: reindex
å få dem indeksert.
Vi legger til koden i produktkontrolleren som tar brukerens innspill og sender den til søkemotoren. I koden nedenfor kaller vi Søke
på Produktmodellen og passere i en blokk. Vi kaller full tekst
metode i blokken og passere i spørringsstrengen som vi ønsker å bli søkt etter. Det finnes flere metoder vi kan bruke her for å spesifisere søkeresultatene vi ønsker. Søkeresultatene blir deretter tildelt @Produkter
som vil være tilgjengelig for vårt syn.
def index @query = Product.search gjør fulltekstparams [: search] end @products = @ query.results end
Kjør programmet, og du bør nå kunne søke gjennom de tilgjengelige produktene.
Solr vil gjøre et sakssensitivt søk gjennom produktnavnene og beskrivelsene ved hjelp av ordet eller setningsinngangen. Du kan få ett felt til å holde mer vekt enn det andre for å forbedre relevansen av søkeresultatene dine. Dette gjøres med øke
metode som er bestått en verdi som bestemmer prioriteten tildelt de forskjellige feltene. Feltet med høyeste verdi vil bære større betydning.
I vår søknad kan vi spesifisere produktene som har den søkte strengen i deres navn for å bli scoret høyere. Vi gjør dette ved å gjøre følgende endringer i /models/product.rb
.
søkbar gjør tekst: navn,: boost => 2 tekst: beskrivelse slutten
Reindex oppføringene med rake sunspot: reindex
og nå blir resultatene med den søkte termen i produktnavnet plassert høyere enn de med uttrykket i beskrivelsen. Du kan legge til flere poster for å teste dette ut.
Fasettert nettlesing er en måte å navigere på søkedata ved hjelp av ulike sett med tilknyttede attributter. For eksempel kan vi i vår søknad klassifisere søk etter produkter etter prisklasse og gi teller av hvert område.
Først legg til pris til søkbar
metode i /models/product.rb
søkbar gjør tekst: navn,: boost => 2 tekst: beskrivelse dobbel: pris slutt
Ring deretter fasett
i kontrolleren. Produktene vil bli fasettert av rekkevidde av prisen i intervaller på $ 100,00. Her antar vi at alle produkter koster mindre enn $ 500.
def index @query = Product.search gjør fulltekstparameter [: søk] fasett: pris,: range => 0 ... 500,: range_interval => 100 med (: pris, Range.new (* params [: price_range] .split "...") .map (&: to_i))) hvis params [: price_range] .present? slutt @products = @ query.results end
I visningsfilen, lim inn følgende på stedet du vil se de fasetterte resultatene.
Søkeresultater
<% for row in @query.facet(:price).rows %>
- <% if params[:price_range].blank? %> <%= link_to row.value, :price_range => row.value,: search => params [: search]%> (<%= row.count %>) <% else %> <%= row.value %> (<%= link_to "X", :price_range => null%>) <% end %>
<% end %>
Nå når du søker etter et begrep, vil det være en liste over fasetter som viser hvor mange resultater som finnes i hvert prisklasse. I vårt eksempelprogram, hvis du søker etter ordet "kamera", vil du se følgende liste.
100,0 ... 200,0 (2) 200,0 ... 300,0 (1) 300,0 ... 400,0 (1)
Hvert element er en kobling og når du klikker på, får du en liste over produktene som oppfyller søkeordet ditt og som også faller inn i prisklassen du klikket på.
Koblingen passerer det opprinnelige søket og det valgte området til indeksaksjonen. Siden det passerer rekkevidden som en streng, bruker vi Range.new (* params [: price_range] .split ("...") .kart (&: til_i))
å konvertere det tilbake til en rekkevidde. Du kan bruke betingede utsagn for å sende ut mer brukervennlige linker som $ 100 - $ 199 (2)
i stedet for 100,0 ... 200,0 (2)
men vi kommer ikke inn i det her.
Det er noen andre konfigurasjoner du kan gjøre på Solr for å tilpasse hvordan det fungerer. I sin standard utfører Sunspot fulltekstsøk ved å dele søkestrengen i tokens basert på hvite plass og andre skilletegn ved hjelp av en smart tokenizer kalt StandardTokenizer
. Deretter er tokens lavere cased og de eksakte ordene er søkt etter.
Dette kan være greit til tider, men det kan også hende du vil konfigurere søkemotoren for å tillate menneskelig feil eller å tillate at forespørsler gjøres som ikke er for strenge. For eksempel vil du kanskje gi noen synonymer til motoren, slik at når brukeren ikke skriver inn den eksakte teksten som er i postene dine, kan de likevel finne lignende resultater. Et eksempel på dette er at du kanskje har et element merket 'ipod' i postene dine. Du kan gi synonymer som 'iPod', 'i-pod' og 'i pod' for å øke oddsene for brukere som finner dataene.
En annen nyttig funksjonalitet du kan legge til stammer, som vil tillate Solr å matche forskjellige ord med samme rot. For eksempel, hvis brukeren skrev inn 'run', ville de få resultater med 'run' og 'running'. Eller hvis de søkte etter 'walk', vil resultatene inkludere data som inneholder 'gange', 'walking', 'walked' og så videre.
Solr-innstillinger finnes i Solr / conf / schema.xml
og det er filen du vil endre for å endre serverens konfigurasjon. Dette er ikke omfattet av denne opplæringen, men for mer om dette, sjekk ut den avanserte fulltekst-konfigurasjonsposten og Solr-wikien.
Nå skal du avslutte Solr-serveren ved å kjøre:
rake sunspot: solr: stop
Vi har sett på hvordan du bruker Sunspot-perlen til å bruke Solr-søkemotoren i en Rails-app. I tillegg til innstillingene vi har brukt, er det mye mer du kan bruke til å tilpasse søkeresultatene dine. Pass på å sjekke Readme-filen for flere alternativer.
Solr gir deg den typen søkefunksjon som ikke er lett å oppnå med vanlige SQL-spørringer. For enkle programmer, med en liten mengde databaseposter, vil SQL-spørringer gjøre uten mye av et resultatstreff. Men hvis du vil ha noe som er skalerbart, så er det verdt å se på Solr eller andre tilgjengelige søkemotorer.