Elasticsearch je iskalnik z json rest api, ki uporablja Lucene in je napisan v Javi. Opis vseh prednosti tega motorja je na voljo na uradna spletna stran. V nadaljevanju bomo Elasticsearch označevali kot ES.
Podobni motorji se uporabljajo za zapletena iskanja v bazi dokumentov. Na primer, iskanje ob upoštevanju morfologije jezika ali iskanje po geografskih koordinatah.
V tem članku bom govoril o osnovah ES na primeru indeksiranja blog objav. Pokazal vam bom, kako filtrirate, razvrščate in iščete dokumente.
Da ne bom odvisen od operacijskega sistema, bom vse zahteve ES poslal s CURL. Obstaja tudi vtičnik za google chrome, imenovan Občutek.
Besedilo vsebuje povezave do dokumentacije in drugih virov. Na koncu so povezave za hiter dostop do dokumentacije. Definicije neznanih izrazov najdete v slovarji.
Namestitev
Za to najprej potrebujemo Javo. Razvijalci priporočam namestite različice Jave, novejše od Jave 8 posodobitev 20 ali Java 7 posodobitev 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 samodejno ustvarjen kazalo blog in Tip post. Lahko potegnemo pogojno analogijo: indeks je zbirka podatkov, tip pa je tabela v tej bazi podatkov. Vsak tip ima svojo shemo − kartiranje, tako kot relacijska tabela. Preslikava se ustvari samodejno, ko je dokument indeksiran:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"
V odgovoru strežnika sem v komentarje dodal vrednosti polj indeksiranega dokumenta:
Omeniti velja, da ES ne razlikuje med eno vrednostjo in nizom vrednosti. Polje z naslovom na primer preprosto vsebuje naslov, polje z oznakami pa vsebuje niz nizov, čeprav so v preslikavi predstavljeni na enak način.
O kartiranju bomo več govorili kasneje.
zahteve
Pridobivanje dokumenta po ID-ju:
# извлечем документ с id 1 типа post из индекса blog
curl -XGET "$ES_URL/blog/post/1?pretty"
V odgovoru so se pojavili novi ključi: _version и _source. Na splošno so vsi ključi, ki se začnejo z _ so razvrščeni kot uradni.
Ključ _version prikazuje različico dokumenta. Potreben je za delovanje optimističnega zaklepnega mehanizma. Na primer, želimo spremeniti dokument, ki ima različico 1. Oddamo spremenjeni dokument in označimo, da gre za urejanje dokumenta z različico 1. Če je nekdo drug urejal tudi dokument z različico 1 in predložil spremembe pred nami, potem ES ne bo sprejel naših sprememb, ker shrani dokument z različico 2.
Ključ _source vsebuje dokument, ki smo ga indeksirali. ES te vrednosti ne uporablja za iskalne operacije, ker Indeksi se uporabljajo za iskanje. Da prihrani prostor, ES shrani stisnjen izvorni dokument. Če potrebujemo samo ID in ne celotnega izvornega dokumenta, lahko onemogočimo izvorno shranjevanje.
Če ne potrebujemo dodatnih informacij, lahko dobimo samo vsebino _source:
curl -XPUT "$ES_URL/blog/post/3" -d'
{
"title": "Как у меня появился котенок",
"content": "<p>Душераздирающая история про бедного котенка с улицы<p>",
"tags": [
"котята"
],
"published_at": "2014-07-21T20:44:42+00:00"
}'
Сортировка
# найдем последний пост по дате публикации и извлечем поля title и published_at
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"size": 1,
"_source": ["title", "published_at"],
"sort": [{"published_at": "desc"}]
}'
Izbrali smo zadnjo objavo. size omejuje število dokumentov, ki jih je treba izdati. total prikazuje skupno število dokumentov, ki ustrezajo zahtevi. sort v izhodu vsebuje matriko celih števil, po katerih se izvaja razvrščanje. Tisti. datum je bil pretvorjen v celo število. Več informacij o razvrščanju najdete v dokumentacijo.
Filtri in poizvedbe
ES od različice 2 ne razlikuje med filtri in poizvedbami uveden je koncept kontekstov.
Kontekst poizvedbe se od konteksta filtra razlikuje po tem, da poizvedba ustvari _score in ni predpomnjena. Kasneje vam bom pokazal, kaj je _score.
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'
Filtriraj po oznakah
Uporaba izrazna poizvedba za iskanje ID-jev dokumentov, ki vsebujejo dano besedo:
# найдем все документы, в поле tags которых есть элемент 'котята'
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": [
"title",
"tags"
],
"filter": {
"term": {
"tags": "котята"
}
}
}'
Če pa iščemo »zgodbe« v vsebinskem polju, ne bomo našli ničesar, ker Kazalo vsebuje samo izvirne besede, ne pa njihovih korenin. Za kakovostno iskanje morate konfigurirati analizator.
Polje _score kaže ustreznost. Če se zahteva izvede v kontekstu filtra, bo vrednost _score vedno enaka 1, kar pomeni popolno ujemanje s filtrom.
Analizatorji
Analizatorji so potrebni za pretvorbo izvornega besedila v nabor žetonov.
Analizatorji so sestavljeni iz enega Tokenizer in več izbirnih TokenFilters. Pred Tokenizerjem je lahko več CharFilters. Tokenizerji razdelijo izvorni niz na žetone, kot so presledki in ločila. TokenFilter lahko spremeni žetone, izbriše ali doda nove, na primer pusti samo koren besede, odstrani predloge, doda sinonime. CharFilter - spremeni celoten izvorni niz, na primer izreže oznake html.
Izkoristimo API in poglejmo, kako standardni in ruski analizatorji preoblikujejo niz "Smešne zgodbe o muckah":
# используем анализатор 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 je razdelil niz na presledke in vse pretvoril v male črke, ruski analizator je odstranil nepomembne besede, jih pretvoril v male črke in pustil koren besed.
Poglejmo, kateri Tokenizer, TokenFilters, CharFilters uporablja ruski analizator:
Najprej bodo vse oznake HTML odstranjene iz izvornega niza, nato ga bo standard tokenizerja razdelil na žetone, nastali žetoni se bodo premaknili v male črke, nepomembne besede bodo odstranjene, preostali žetoni pa bodo ostali jedro besede.
Ustvarjanje indeksa
Zgoraj smo opisali privzeti analizator. Veljal bo za vsa polja nizov. Naša objava vsebuje niz oznak, zato bo analize obdelal tudi oznake. Ker Objave iščemo po natančnem ujemanju z oznako, nato pa moramo onemogočiti analizo za polje oznak.
Ustvarimo indeks blog2 z analizatorjem in preslikavo, v katerem je onemogočena analiza polja oznak:
Dodajmo iste 3 objave v ta indeks (blog2). Ta postopek bom izpustil, ker... je podobno dodajanju dokumentov v kazalo spletnega dnevnika.
Iskanje po celotnem besedilu s podporo za izraze
Oglejmo si še eno vrsto zahtev:
# найдем документы, в которых встречается слово 'истории'
# 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"
]
}
}
}'
Ker Uporabljamo analizator z ruskim korenom, potem bo ta zahteva vrnila vse dokumente, čeprav vsebujejo samo besedo 'zgodovina'.
Zahteva lahko vsebuje posebne znake, na primer:
""fried eggs" +(eggplant | potato) -frittata"
Sintaksa zahteve:
+ 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 поста про котиков
Če vas zanimajo podobni članki-lekcije, imate ideje za nove članke ali imate predloge za sodelovanje, bom vesel sporočila v osebnem sporočilu ali po e-pošti [e-pošta zaščitena].