Elasticsearch është një motor kërkimi me json rest api, duke përdorur Lucene dhe i shkruar në Java. Një përshkrim i të gjitha avantazheve të këtij motori është në dispozicion në faqen zyrtare të internetit. Në atë që vijon do t'i referohemi Elasticsearch si ES.
Motorë të ngjashëm përdoren për kërkime komplekse në një bazë të dhënash dokumentesh. Për shembull, kërkoni duke marrë parasysh morfologjinë e gjuhës ose kërkoni sipas koordinatave gjeografike.
Në këtë artikull do të flas për bazat e ES duke përdorur shembullin e indeksimit të postimeve në blog. Unë do t'ju tregoj se si të filtroni, renditni dhe kërkoni dokumente.
Për të mos varur nga sistemi operativ, do t'i bëj të gjitha kërkesat ES duke përdorur CURL. Ekziston edhe një shtojcë për google chrome që quhet kuptim.
Teksti përmban lidhje me dokumentacionin dhe burime të tjera. Në fund ka lidhje për akses të shpejtë në dokumentacion. Përkufizimet e termave të panjohur mund të gjenden në fjalorë.
Instalimi
Për ta bërë këtë, së pari na duhet Java. Zhvilluesit rekomandoj instaloni versionet Java më të reja se përditësimi 8 i Java 20 ose përditësimi 7 i Java 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 u krijua automatikisht indeks blog dhe një tip postim. Ne mund të nxjerrim një analogji të kushtëzuar: një indeks është një bazë të dhënash, dhe një lloj është një tabelë në këtë bazë të dhënash. Çdo lloj ka skemën e vet − planifikim, ashtu si një tabelë relacionale. Hartimi gjenerohet automatikisht kur dokumenti indeksohet:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"
Në përgjigjen e serverit, shtova vlerat e fushave të dokumentit të indeksuar në komente:
Vlen të përmendet se ES nuk bën dallim midis një vlere të vetme dhe një grupi vlerash. Për shembull, fusha e titullit thjesht përmban një titull, dhe fusha e etiketave përmban një grup vargjesh, megjithëse ato përfaqësohen në të njëjtën mënyrë në hartografi.
Ne do të flasim më shumë për hartën më vonë.
Kërkesat
Marrja e një dokumenti me ID-në e tij:
# извлечем документ с id 1 типа post из индекса blog
curl -XGET "$ES_URL/blog/post/1?pretty"
Në përgjigje u shfaqën çelësa të rinj: _version и _source. Në përgjithësi, të gjithë çelësat duke filluar me _ klasifikohen si zyrtare.
Ключ _version tregon versionin e dokumentit. Është e nevojshme që mekanizmi optimist i mbylljes të funksionojë. Për shembull, ne duam të ndryshojmë një dokument që ka versionin 1. Ne dorëzojmë dokumentin e ndryshuar dhe tregojmë se ky është një modifikim i një dokumenti me versionin 1. Nëse dikush tjetër gjithashtu ka redaktuar një dokument me versionin 1 dhe ka paraqitur ndryshime para nesh, atëherë ES nuk do të pranojë ndryshimet tona, sepse ruan dokumentin me versionin 2.
Ключ _source përmban dokumentin që kemi indeksuar. ES nuk e përdor këtë vlerë për operacionet e kërkimit sepse Indekset përdoren për kërkim. Për të kursyer hapësirë, ES ruan një dokument burim të ngjeshur. Nëse na duhet vetëm ID-ja dhe jo i gjithë dokumenti burimor, atëherë mund të çaktivizojmë ruajtjen e burimit.
Nëse nuk kemi nevojë për informacion shtesë, mund të marrim vetëm përmbajtjen e _source:
curl -XPUT "$ES_URL/blog/post/3" -d'
{
"title": "Как у меня появился котенок",
"content": "<p>Душераздирающая история про бедного котенка с улицы<p>",
"tags": [
"котята"
],
"published_at": "2014-07-21T20:44:42+00:00"
}'
klasifikim
# найдем последний пост по дате публикации и извлечем поля title и published_at
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"size": 1,
"_source": ["title", "published_at"],
"sort": [{"published_at": "desc"}]
}'
Ne zgjodhëm postimin e fundit. size kufizon numrin e dokumenteve që do të lëshohen. total tregon numrin total të dokumenteve që përputhen me kërkesën. sort në dalje përmban një grup numrash të plotë me të cilin kryhet renditja. Ato. data u konvertua në një numër të plotë. Më shumë informacion rreth renditjes mund të gjeni në dokumentacionin.
Filtra dhe pyetje
ES që nga versioni 2 nuk bën dallim midis filtrave dhe pyetjeve, përkundrazi prezantohet koncepti i konteksteve.
Konteksti i pyetjes ndryshon nga një kontekst filtri në atë që pyetja gjeneron një _score dhe nuk ruhet në memorie. Unë do t'ju tregoj se çfarë është _score më vonë.
Filtro sipas datës
Ne përdorim kërkesën varg në kontekstin e filtrit:
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'
Filtro sipas etiketave
Ne përdorim pyetje termi për të kërkuar ID dokumentesh që përmbajnë një fjalë të caktuar:
# найдем все документы, в поле tags которых есть элемент 'котята'
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": [
"title",
"tags"
],
"filter": {
"term": {
"tags": "котята"
}
}
}'
Megjithatë, nëse kërkojmë për “histori” në fushën e përmbajtjes, nuk do të gjejmë asgjë, sepse Indeksi përmban vetëm fjalët origjinale, jo rrënjët e tyre. Për të bërë një kërkim me cilësi të lartë, duhet të konfiguroni analizuesin.
Fushë _score tregon rëndësinë. Nëse kërkesa ekzekutohet në një kontekst filtri, atëherë vlera _score do të jetë gjithmonë e barabartë me 1, që do të thotë një përputhje e plotë me filtrin.
analizues
analizues nevojiten për të kthyer tekstin burimor në një grup shenjash.
Analizatorët përbëhen nga një Tokenizues dhe disa opsionale TokenFilters. Tokenizuesi mund të paraprihet nga disa Charfilters. Tokenizuesit thyejnë vargun burimor në shenja, të tilla si hapësira dhe karaktere pikësimi. TokenFilter mund të ndryshojë shenja, të fshijë ose të shtojë të reja, për shembull, të lërë vetëm rrënjën e fjalës, të heqë parafjalët, të shtojë sinonime. CharFilter - ndryshon të gjithë vargun e burimit, për shembull, shkurton etiketat html.
Le të përfitojmë api dhe le të shohim se si analizuesit standardë dhe rusë transformojnë vargun "Tregime qesharake për kotele":
# используем анализатор 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"
Analizatori standard ndau vargun në hapësira dhe konvertoi gjithçka në shkronja të vogla, analizuesi rus hoqi fjalët e parëndësishme, e shndërroi atë në shkronja të vogla dhe la bazën e fjalëve.
Le të shohim se cilët Tokenizer, TokenFilters, CharFilters përdor analizuesi rus:
Le të përshkruajmë analizuesin tonë bazuar në Rusisht, i cili do të presë etiketat html. Le ta quajmë të paracaktuar, sepse Një analizues me këtë emër do të përdoret si parazgjedhje.
Së pari, të gjitha etiketat HTML do të hiqen nga vargu burimor, më pas standardi i tokenizuesit do ta ndajë atë në shenja, shenjat që rezultojnë do të kalojnë në shkronja të vogla, fjalët e parëndësishme do të hiqen dhe shenjat e mbetura do të mbeten burimi i fjalës.
Krijimi i një Indeksi
Më sipër kemi përshkruar analizuesin e paracaktuar. Do të zbatohet për të gjitha fushat e vargut. Postimi ynë përmban një sërë etiketash, kështu që etiketat do të përpunohen gjithashtu nga analizuesi. Sepse Ne po kërkojmë postime sipas përputhjes së saktë me një etiketë, atëherë duhet të çaktivizojmë analizën për fushën e etiketave.
Le të krijojmë një blog indeks2 me një analizues dhe hartografi, në të cilin analiza e fushës së etiketave është e çaktivizuar:
Le të shtojmë të njëjtat 3 postime në këtë indeks (blog2). Do ta heq këtë proces sepse... është e ngjashme me shtimin e dokumenteve në indeksin e blogut.
Kërkimi i tekstit të plotë me mbështetje të shprehjes
Le të hedhim një vështrim në një lloj tjetër kërkese:
# найдем документы, в которых встречается слово 'истории'
# 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"
]
}
}
}'
Sepse Ne po përdorim një analizues me origjinë ruse, atëherë kjo kërkesë do të kthejë të gjitha dokumentet, megjithëse ato përmbajnë vetëm fjalën "histori".
Kërkesa mund të përmbajë karaktere të veçanta, për shembull:
""fried eggs" +(eggplant | potato) -frittata"
Kërko sintaksë:
+ 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 поста про котиков
Nëse jeni të interesuar për artikuj-mësime të ngjashme, keni ide për artikuj të rinj, ose keni propozime për bashkëpunim, atëherë do të jem i lumtur të marr një mesazh në një mesazh personal ose me email [email mbrojtur].