Elasticsearch er leitarvél með JSON REST API, sem notar Lucene og er skrifuð í Java. Lýsing á öllum kostum þessarar leitarvélar er að finna á Héðan í frá munum við vísa til Elasticsearch sem ES.
Slíkar leitarvélar eru notaðar fyrir flóknar leitir í gagnagrunnum, svo sem leit byggða á málfræðilegri formgerð eða leit eftir landfræðilegum hnitum.
Í þessari grein mun ég fjalla um grunnatriði ES með því að nota dæmi um flokkun bloggfærslna. Ég mun sýna þér hvernig á að sía, flokka og leita í skjölum.
Til að vera óháður stýrikerfinu mun ég nota CURL til að senda allar ES beiðnir mínar. Það er líka viðbót fyrir Google Chrome sem kallast .
Tenglar á skjöl og aðrar heimildir eru í gegnum allan textann. Tenglar með fljótlegum aðgangi að skjölunum eru í lokin. Skilgreiningar á ókunnuglegum hugtökum er að finna í .
Uppsetning ES
Til þess þurfum við fyrst Java. Forritarar Settu upp Java útgáfur nýrri en Java 8 uppfærsla 20 eða Java 7 uppfærsla 55.
Dreifing ES er aðgengileg á Eftir að þú hefur tekið upp skjalasafnið þarftu að keyra bin/elasticsearchEinnig fáanlegt . Það er . .
Eftir uppsetningu og ræsingu skulum við athuga virknina:
# для удобства запомним адрес в переменную
#export ES_URL=$(docker-machine ip dev):9200
export ES_URL=localhost:9200
curl -X GET $ES_URLVið munum fá svar sem lítur eitthvað svona út:
{
"name" : "Heimdall",
"cluster_name" : "elasticsearch",
"version" : {
"number" : "2.2.1",
"build_hash" : "d045fc29d1932bce18b2e65ab8b297fbf6cd41a1",
"build_timestamp" : "2016-03-09T09:38:54Z",
"build_snapshot" : false,
"lucene_version" : "5.4.1"
},
"tagline" : "You Know, for Search"
}Flokkun
Við skulum bæta við færslu í ES:
# Добавим документ 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"
}'
svar netþjóns:
{
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : false
}
ES búið til sjálfkrafa blogg og staða. Hægt er að draga grófa samlíkingu: vísitala er gagnagrunnur og tegund er tafla innan þess gagnagrunns. Hver tegund hefur sitt eigið skema— , rétt eins og tengslatafla. Vörpun er búin til sjálfkrafa þegar skjal er skráð:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"Í svari netþjónsins bætti ég við reitgildum vísitöluskrárinnar í athugasemdunum:
{
"blog" : {
"mappings" : {
"post" : {
"properties" : {
/* "content": "<p>Смешная история про котят<p>", */
"content" : {
"type" : "string"
},
/* "published_at": "2014-09-12T20:44:42+00:00" */
"published_at" : {
"type" : "date",
"format" : "strict_date_optional_time||epoch_millis"
},
/* "tags": ["котята", "смешная история"] */
"tags" : {
"type" : "string"
},
/* "title": "Веселые котята" */
"title" : {
"type" : "string"
}
}
}
}
}
}Það er vert að taka fram að ES gerir ekki greinarmun á einu gildi og fylki af gildum. Til dæmis inniheldur titilreiturinn aðeins titil, en tagsreiturinn inniheldur fylki af strengjum, jafnvel þótt þeir séu táknaðir eins í vörpuninni.
Við munum ræða kortlagningu nánar síðar.
Beiðnir
Að draga út skjal eftir auðkenni þess:
# извлечем документ с id 1 типа post из индекса blog
curl -XGET "$ES_URL/blog/post/1?pretty"{
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"title" : "Веселые котята",
"content" : "<p>Смешная история про котят<p>",
"tags" : [ "котята", "смешная история" ],
"published_at" : "2014-09-12T20:44:42+00:00"
}
}Nýir lyklar birtust í svarinu: _version и _sourceAlmennt séð allir lyklar sem byrja á _ eru flokkaðar sem þjónustuvörur.
Lykill _version Sýnir útgáfu skjalsins. Þetta er nauðsynlegt til þess að bjartsýnislæsingarkerfið virki. Til dæmis viljum við breyta skjali með útgáfu 1. Við sendum inn breytta skjalið og gefum til kynna að þetta sé útgáfa af skjalinu með útgáfu 1. Ef einhver annar breytti einnig skjalinu með útgáfu 1 og sendi breytingarnar inn fyrir okkur, mun ES ekki samþykkja breytingar okkar, þar sem það geymir skjalið með útgáfu 2.
Lykill _source Inniheldur skjalið sem við flokkuðum. ES notar ekki þetta gildi fyrir leitaraðgerðir, þar sem vísitölur eru notaðar til leitar. Til að spara pláss geymir ES þjappaða útgáfu af upprunalega skjalinu. Ef við þurfum aðeins auðkennið en ekki allt upprunalega skjalið getum við gert geymslu á upprunalega skjalinu óvirka.
Ef við þurfum ekki frekari upplýsingar getum við aðeins fengið innihald _source:
curl -XGET "$ES_URL/blog/post/1/_source?pretty"{
"title" : "Веселые котята",
"content" : "<p>Смешная история про котят<p>",
"tags" : [ "котята", "смешная история" ],
"published_at" : "2014-09-12T20:44:42+00:00"
}
Þú getur líka valið aðeins ákveðna reiti:
# извлечем только поле title
curl -XGET "$ES_URL/blog/post/1?_source=title&pretty"{
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"title" : "Веселые котята"
}
}Við skulum vísitöluera nokkrar færslur í viðbót og keyra flóknari fyrirspurnir.
curl -XPUT "$ES_URL/blog/post/2" -d'
{
"title": "Веселые щенки",
"content": "<p>Смешная история про щенков<p>",
"tags": [
"щенки",
"смешная история"
],
"published_at": "2014-08-12T20:44:42+00:00"
}'curl -XPUT "$ES_URL/blog/post/3" -d'
{
"title": "Как у меня появился котенок",
"content": "<p>Душераздирающая история про бедного котенка с улицы<p>",
"tags": [
"котята"
],
"published_at": "2014-07-21T20:44:42+00:00"
}'Raða
# найдем последний пост по дате публикации и извлечем поля title и published_at
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"size": 1,
"_source": ["title", "published_at"],
"sort": [{"published_at": "desc"}]
}'{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : null,
"hits" : [ {
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_score" : null,
"_source" : {
"title" : "Веселые котята",
"published_at" : "2014-09-12T20:44:42+00:00"
},
"sort" : [ 1410554682000 ]
} ]
}
}Við höfum valið síðustu færsluna. size takmarkar fjölda útgefinna skjala. total sýnir heildarfjölda skjala sem passa við fyrirspurnina. sort Úttakið inniheldur fylki af heiltölum sem flokkunin er framkvæmd með. Það er að segja, dagsetningin hefur verið breytt í heiltölu. Nánari upplýsingar um flokkun er að finna í .
Síur og fyrirspurnir
ES frá útgáfu 2 gerir ekki greinarmun á síum og fyrirspurnum, heldur .
Fyrirspurnarsamhengið er frábrugðið síunarsamhenginu að því leyti að fyrirspurnin býr til _stig og er ekki geymd í skyndiminni. Ég mun útskýra hvað _stig er síðar.
Sía eftir dagsetningu
Að nota fyrirspurnina í samhengi við síu:
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'Sía eftir merkjum
Við notum Til að leita að skjalakennum sem innihalda tiltekið orð:
# найдем все документы, в поле tags которых есть элемент 'котята'
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": [
"title",
"tags"
],
"filter": {
"term": {
"tags": "котята"
}
}
}'{
"took" : 9,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [ {
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "Веселые котята",
"tags" : [ "котята", "смешная история" ]
}
}, {
"_index" : "blog",
"_type" : "post",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"title" : "Как у меня появился котенок",
"tags" : [ "котята" ]
}
} ]
}
}Leit í fullum texta
Þrjú skjöl okkar innihalda eftirfarandi í efnisreitnum:
<p>Смешная история про котят<p><p>Смешная история про щенков<p><p>Душераздирающая история про бедного котенка с улицы<p>
Við notum Til að leita að skjalakennum sem innihalda tiltekið orð:
# source: false означает, что не нужно извлекать _source найденных документов
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": false,
"query": {
"match": {
"content": "история"
}
}
}'{
"took" : 13,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 0.11506981,
"hits" : [ {
"_index" : "blog",
"_type" : "post",
"_id" : "2",
"_score" : 0.11506981
}, {
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_score" : 0.11506981
}, {
"_index" : "blog",
"_type" : "post",
"_id" : "3",
"_score" : 0.095891505
} ]
}
}Hins vegar, ef við leitum að „sögum“ í efnisreitnum, munum við ekki finna neitt, þar sem leitarorðaskráin inniheldur aðeins frumorð, ekki stofna þeirra. Til að framkvæma gæðaleit þurfum við að stilla greiningartækið.
Field _score sýnir Ef fyrirspurnin er keyrð í síusamhengi verður _score gildið alltaf 1, sem þýðir að sían passar fullkomlega.
Greiningartæki
eru nauðsynleg til að umbreyta frumtextanum í safn af táknum.
Greiningartækin samanstanda af einum og nokkrir valfrjálsir Táknmyndari getur komið á undan nokkrum Táknmyndavélar brjóta upprunastreng niður í tákn, til dæmis með bilum og greinarmerkjatáknum. Táknmyndavélar geta breytt táknum, fjarlægt þau eða bætt við nýjum, til dæmis með því að skilja aðeins eftir orðstofninn, fjarlægja forsetningar eða bæta við samheitum. Merkjamyndavélar breyta upprunastrengnum alveg, til dæmis með því að fjarlægja HTML-merki.
Það eru nokkrir í ES Til dæmis, greiningartæki .
Nýtum okkur og við skulum sjá hvernig staðlaðir og rússneskir greiningarforrit umbreyta strengnum „Fyndar sögur um kettlinga“:
# используем анализатор 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"{
"tokens" : [ {
"token" : "веселые",
"start_offset" : 0,
"end_offset" : 7,
"type" : "<ALPHANUM>",
"position" : 0
}, {
"token" : "истории",
"start_offset" : 8,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 1
}, {
"token" : "про",
"start_offset" : 16,
"end_offset" : 19,
"type" : "<ALPHANUM>",
"position" : 2
}, {
"token" : "котят",
"start_offset" : 20,
"end_offset" : 25,
"type" : "<ALPHANUM>",
"position" : 3
} ]
}# используем анализатор russian
curl -XGET "$ES_URL/_analyze?pretty&analyzer=russian&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"{
"tokens" : [ {
"token" : "весел",
"start_offset" : 0,
"end_offset" : 7,
"type" : "<ALPHANUM>",
"position" : 0
}, {
"token" : "истор",
"start_offset" : 8,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 1
}, {
"token" : "кот",
"start_offset" : 20,
"end_offset" : 25,
"type" : "<ALPHANUM>",
"position" : 3
} ]
}Staðlaða greiningartækið skipti strengnum við bil og breytti öllu í lágstafi, rússneska greiningartækið fjarlægði ómerkileg orð, breytti þeim í lágstafi og skildi orðstofnana eftir.
Við skulum sjá hvaða Tokenizer, TokenFilters og CharFilters rússneski greiningartækið notar:
{
"filter": {
"russian_stop": {
"type": "stop",
"stopwords": "_russian_"
},
"russian_keywords": {
"type": "keyword_marker",
"keywords": []
},
"russian_stemmer": {
"type": "stemmer",
"language": "russian"
}
},
"analyzer": {
"russian": {
"tokenizer": "standard",
/* TokenFilters */
"filter": [
"lowercase",
"russian_stop",
"russian_keywords",
"russian_stemmer"
]
/* CharFilters отсутствуют */
}
}
}Við skulum lýsa okkar eigin rússneska greiningarforriti sem fjarlægir HTML-tagga. Við munum kalla það sjálfgefið forrit, þar sem þetta verður sjálfgefið forrit.
{
"filter": {
"ru_stop": {
"type": "stop",
"stopwords": "_russian_"
},
"ru_stemmer": {
"type": "stemmer",
"language": "russian"
}
},
"analyzer": {
"default": {
/* добавляем удаление html тегов */
"char_filter": ["html_strip"],
"tokenizer": "standard",
"filter": [
"lowercase",
"ru_stop",
"ru_stemmer"
]
}
}
}Fyrst verða öll HTML-tögg fjarlægð úr upprunastrengnum, síðan verður honum skipt í tákn með táknunarstaðlinum (tokenizer), táknin sem myndast verða breytt í lágstafi, ómerkileg orð verða fjarlægð og táknin sem eftir eru verða orðstofninn.
Að búa til vísitölu
Hér að ofan lýstum við sjálfgefna greiningartækinu. Það verður notað á alla strengjasvið. Færslan okkar inniheldur fylki af merkjum, þannig að greiningartækið mun einnig vinna úr merkjunum. Þar sem við erum að leita að færslum sem passa nákvæmlega við merkið þurfum við að slökkva á greiningu fyrir reitinn „merki“.
Við skulum búa til blog2 vísitölu með greiningartæki og vörpun, þar sem greining á merkjasviðinu er óvirk:
curl -XPOST "$ES_URL/blog2" -d'
{
"settings": {
"analysis": {
"filter": {
"ru_stop": {
"type": "stop",
"stopwords": "_russian_"
},
"ru_stemmer": {
"type": "stemmer",
"language": "russian"
}
},
"analyzer": {
"default": {
"char_filter": [
"html_strip"
],
"tokenizer": "standard",
"filter": [
"lowercase",
"ru_stop",
"ru_stemmer"
]
}
}
}
},
"mappings": {
"post": {
"properties": {
"content": {
"type": "string"
},
"published_at": {
"type": "date"
},
"tags": {
"type": "string",
"index": "not_analyzed"
},
"title": {
"type": "string"
}
}
}
}
}'Við skulum bæta sömu þremur færslunum við þessa vísitölu (blogg2). Ég sleppi þessu ferli, þar sem það er svipað og að bæta skjölum við bloggvísitöluna.
Leit að fullum texta með stuðningi við tjáningar
Við skulum kynna okkur aðra tegund fyrirspurnar:
# найдем документы, в которых встречается слово 'истории'
# 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"
]
}
}
}'Þar sem við notum greiningartæki með rússneskri stofnsetningu mun þessi fyrirspurn skila öllum skjölum, jafnvel þótt þau innihaldi aðeins orðið „history“.
Fyrirspurnin getur innihaldið sérstafi, til dæmis:
""fried eggs" +(eggplant | potato) -frittata"Fyrirspurnarsetningafræði:
+ 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 поста про котиковtilvísanir
PS
Ef þú hefur áhuga á svipuðum kennslugreinum, hefur hugmyndir að nýjum greinum eða hefur einhverjar tillögur að samstarfi, þá myndi ég gjarnan heyra frá þér í gegnum einkaskilaboð eða tölvupóst á m.kuzmin+habr@darkleaf.ru.
Heimild: www.habr.com
