Elasticsearch je tražilica s json rest api, koja koristi Lucene i napisana je u Javi. Opis svih prednosti ovog motora dostupan je na službene web stranice. U nastavku ćemo Elasticsearch nazivati ES.
Slični se strojevi koriste za složena pretraživanja u bazi podataka dokumenata. Na primjer, pretražite uzimajući u obzir morfologiju jezika ili pretražite po geokoordinatama.
U ovom ću članku govoriti o osnovama ES-a na primjeru indeksiranja postova na blogu. Pokazat ću vam kako filtrirati, sortirati i pretraživati dokumente.
Kako ne bih ovisio o operativnom sustavu, sve ću zahtjeve ES-u uputiti pomoću CURL-a. Postoji i dodatak za google chrome pod nazivom osjećaj.
Tekst sadrži poveznice na dokumentaciju i druge izvore. Na kraju se nalaze poveznice za brzi pristup dokumentaciji. Definicije nepoznatih pojmova mogu se pronaći u glossarii.
Instalacija ES-a
Da bismo to učinili, prvo nam je potrebna Java. Programeri Preporučiti instalirajte verzije Java novije od Java 8 update 20 ili Java 7 update 55.
# Добавим документ c id 1 типа post в индекс blog.
# ?pretty указывает, что вывод должен быть человеко-читаемым.
curl -XPUT "$ES_URL/blog/post/1?pretty" -d'
{
"title": "Веселые котята",
"content": "<p>Смешная история про котят<p>",
"tags": [
"котята",
"смешная история"
],
"published_at": "2014-09-12T20:44:42+00:00"
}'
ES automatski stvoren indeks blog i тип objaviti. Možemo povući uvjetnu analogiju: indeks je baza podataka, a tip je tablica u ovoj bazi podataka. Svaki tip ima svoju shemu − kartografija, baš kao relacijska tablica. Mapiranje se generira automatski kada se dokument indeksira:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"
U odgovoru poslužitelja dodao sam vrijednosti polja indeksiranog dokumenta u komentarima:
Vrijedno je napomenuti da ES ne razlikuje jednu vrijednost od niza vrijednosti. Na primjer, polje naslova jednostavno sadrži naslov, a polje oznaka sadrži niz nizova, iako su oni predstavljeni na isti način u mapiranju.
Kasnije ćemo više govoriti o mapiranju.
Upiti
Dohvaćanje dokumenta prema njegovom ID-u:
# извлечем документ с id 1 типа post из индекса blog
curl -XGET "$ES_URL/blog/post/1?pretty"
U odgovoru su se pojavili novi ključevi: _version и _source. Općenito, svi ključevi koji počinju s _ klasificirani su kao službeni.
ključ _version prikazuje verziju dokumenta. Potreban je za rad optimističnog mehanizma za zaključavanje. Na primjer, želimo promijeniti dokument koji ima verziju 1. Predajemo promijenjeni dokument i označavamo da je ovo uređivanje dokumenta s verzijom 1. Ako je netko drugi također uredio dokument s verzijom 1 i poslao izmjene prije nas, tada ES neće prihvatiti naše izmjene, jer pohranjuje dokument s verzijom 2.
ključ _source sadrži dokument koji smo indeksirali. ES ne koristi ovu vrijednost za operacije pretraživanja jer Za pretraživanje se koriste indeksi. Radi uštede prostora, ES pohranjuje komprimirani izvorni dokument. Ako trebamo samo ID, a ne cijeli izvorni dokument, tada možemo onemogućiti izvornu pohranu.
Ako nam ne trebaju dodatne informacije, možemo dobiti samo sadržaj _source:
curl -XPUT "$ES_URL/blog/post/3" -d'
{
"title": "Как у меня появился котенок",
"content": "<p>Душераздирающая история про бедного котенка с улицы<p>",
"tags": [
"котята"
],
"published_at": "2014-07-21T20:44:42+00:00"
}'
sortiranje
# найдем последний пост по дате публикации и извлечем поля title и published_at
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"size": 1,
"_source": ["title", "published_at"],
"sort": [{"published_at": "desc"}]
}'
Izabrali smo zadnji post. size ograničava broj dokumenata koji se izdaju. total prikazuje ukupan broj dokumenata koji odgovaraju zahtjevu. sort u izlazu sadrži niz cijelih brojeva po kojima se vrši sortiranje. Oni. datum je pretvoren u cijeli broj. Više informacija o sortiranju možete pronaći u dokumentacija.
Filtri i upiti
Umjesto toga, ES od verzije 2 ne razlikuje filtre i upite uvodi se pojam konteksta.
Kontekst upita razlikuje se od konteksta filtra po tome što upit generira _score i nije predmemoriran. Kasnije ću vam pokazati što je _score.
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'
Filtriraj po oznakama
Koristimo termin upit za traženje ID-ova dokumenata koji sadrže zadanu riječ:
# найдем все документы, в поле tags которых есть элемент 'котята'
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": [
"title",
"tags"
],
"filter": {
"term": {
"tags": "котята"
}
}
}'
Međutim, ako tražimo “priče” u polju sadržaja, nećemo pronaći ništa, jer Indeks sadrži samo izvorne riječi, a ne njihov korijen. Kako biste izvršili kvalitetno pretraživanje, morate konfigurirati analizator.
Polje _score pokazuje relevantnost. Ako se zahtjev izvršava u kontekstu filtra, tada će vrijednost _score uvijek biti jednaka 1, što znači potpuno podudaranje s filtrom.
analizatori
analizatori potrebni su za pretvaranje izvornog teksta u skup tokena.
Analizatori se sastoje od jednog Tokenizator i nekoliko izbornih TokenFilters. Tokenizeru može prethoditi nekoliko CharFilters. Tokenizatori rastavljaju izvorni niz na tokene, kao što su razmaci i interpunkcijski znakovi. TokenFilter može mijenjati tokene, brisati ili dodavati nove, na primjer, ostaviti samo korijen riječi, ukloniti prijedloge, dodati sinonime. CharFilter - mijenja cijeli izvorni niz, na primjer, izrezuje html oznake.
Iskoristimo api i pogledajmo kako standardni i ruski analizatori transformiraju niz "Smiješne priče o mačićima":
# используем анализатор standard
# обязательно нужно перекодировать не ASCII символы
curl -XGET "$ES_URL/_analyze?pretty&analyzer=standard&text=%D0%92%D0%B5%D1%81%D0%B5%D0%BB%D1%8B%D0%B5%20%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B8%20%D0%BF%D1%80%D0%BE%20%D0%BA%D0%BE%D1%82%D1%8F%D1%82"
Standardni analizator podijelio je niz razmacima i sve pretvorio u mala slova, ruski analizator uklonio je nevažne riječi, pretvorio ih u mala slova i ostavio korijen riječi.
Da vidimo koji Tokenizer, TokenFilters, CharFilters koristi ruski analizator:
Opišimo naš analizator temeljen na ruskom, koji će izrezati html oznake. Nazovimo to zadanim, jer analizator s ovim nazivom koristit će se prema zadanim postavkama.
Najprije će se sve HTML oznake ukloniti iz izvornog niza, zatim će ga standard tokenizera podijeliti na tokene, rezultirajući tokeni premjestit će se u mala slova, beznačajne riječi će biti uklonjene, a preostali tokeni ostat će korijen riječi.
Izrada indeksa
Gore smo opisali zadani analizator. Primijenit će se na sva polja nizova. Naš post sadrži niz oznaka, tako da će oznake također biti obrađene od strane analizatora. Jer Tražimo objave prema točnom podudaranju s oznakom, a zatim moramo onemogućiti analizu za polje oznaka.
Kreirajmo indeksni blog2 s analizatorom i mapiranjem, u kojem je analiza polja oznaka onemogućena:
Dodajmo ista 3 posta u ovaj indeks (blog2). Izostavit ću ovaj proces jer... to je slično dodavanju dokumenata u indeks bloga.
Pretraživanje cijelog teksta s podrškom za izraze
Pogledajmo drugu vrstu zahtjeva:
# найдем документы, в которых встречается слово 'истории'
# query -> simple_query_string -> query содержит поисковый запрос
# поле title имеет приоритет 3
# поле tags имеет приоритет 2
# поле content имеет приоритет 1
# приоритет используется при ранжировании результатов
curl -XPOST "$ES_URL/blog2/post/_search?pretty" -d'
{
"query": {
"simple_query_string": {
"query": "истории",
"fields": [
"title^3",
"tags^2",
"content"
]
}
}
}'
Jer Koristimo analizator s ruskim korijenom, tada će ovaj zahtjev vratiti sve dokumente, iako sadrže samo riječ 'povijest'.
Zahtjev može sadržavati posebne znakove, na primjer:
""fried eggs" +(eggplant | potato) -frittata"
Sintaksa zahtjeva:
+ signifies AND operation
| signifies OR operation
- negates a single token
" wraps a number of tokens to signify a phrase for searching
* at the end of a term signifies a prefix query
( and ) signify precedence
~N after a word signifies edit distance (fuzziness)
~N after a phrase signifies slop amount
# найдем документы без слова 'щенки'
curl -XPOST "$ES_URL/blog2/post/_search?pretty" -d'
{
"query": {
"simple_query_string": {
"query": "-щенки",
"fields": [
"title^3",
"tags^2",
"content"
]
}
}
}'
# получим 2 поста про котиков
Ako ste zainteresirani za slične članke-lekcije, imate ideje za nove članke ili imate prijedloge za suradnju, bit će mi drago primiti poruku u osobnoj poruci ili e-poštom [e-pošta zaštićena].