Elasticsearch se yon motè rechèch ak json rès api, lè l sèvi avèk Lucene ak ekri nan Java. Yon deskripsyon tout avantaj ki genyen nan motè sa a disponib nan . Nan sa ki anba a nou pral refere a Elasticsearch kòm ES.
Motè menm jan yo itilize pou rechèch konplèks nan yon baz done dokiman. Pa egzanp, chèche pran an kont mòfoloji lang lan oswa rechèch pa kowòdone geo.
Nan atik sa a mwen pral pale sou Basics yo nan ES lè l sèvi avèk egzanp lan nan Indexing pòs blog. Mwen pral montre w kijan pou filtre, triye ak rechèch dokiman yo.
Pou m pa depann de sistèm operasyon an, mwen pral fè tout demann bay ES lè l sèvi avèk CURL. Genyen tou yon plugin pou google chrome rele .
Tèks la gen lyen ki mennen nan dokiman ak lòt sous. Nan fen a gen lyen pou aksè rapid nan dokiman an. Ou ka jwenn definisyon tèm ki pa abitye nan .
Enstalasyon
Pou fè sa, nou bezwen premye Java. Devlopè enstale vèsyon Java ki pi nouvo pase Java 8 aktyalizasyon 20 oswa Java 7 aktyalizasyon 55.
Distribisyon ES la disponib nan . Apre debake achiv la ou bezwen kouri bin/elasticsearch. Disponib tou . Genyen . .
Apre enstalasyon ak lansman, ann tcheke fonksyonalite a:
# для удобства запомним адрес в переменную
#export ES_URL=$(docker-machine ip dev):9200
export ES_URL=localhost:9200
curl -X GET $ES_URLNou pral resevwa yon bagay tankou sa a:
{
"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"
}Indexing
Ann ajoute yon pòs nan 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"
}'
repons sèvè:
{
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : false
}
ES otomatikman kreye blog ak poste. Nou ka trase yon analoji kondisyonèl: yon endèks se yon baz done, ak yon kalite se yon tab nan baz done sa a. Chak kalite gen pwòp konplo li - , jis tankou yon tab relasyon. Kat yo pwodwi otomatikman lè dokiman an endis:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"Nan repons sèvè a, mwen te ajoute valè jaden dokiman endis la nan kòmantè yo:
{
"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"
}
}
}
}
}
}Li vo sonje ke ES pa fè diferans ant yon valè sèl ak yon etalaj de valè. Pou egzanp, jaden tit la tou senpleman gen yon tit, ak jaden tags la gen yon etalaj de fisèl, byenke yo reprezante nan menm fason an nan kat.
Nou pral pale plis sou kat pita.
Demann
Rekipere yon dokiman pa id li:
# извлечем документ с 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"
}
}Nouvo kle parèt nan repons lan: _version и _source. An jeneral, tout kle kòmanse ak _ yo klase kòm ofisyèl.
Kle _version montre vèsyon dokiman an. Li nesesè pou mekanis optimis bloke a travay. Pou egzanp, nou vle chanje yon dokiman ki gen vèsyon 1. Nou soumèt dokiman ki chanje a epi endike ke sa a se yon modifikasyon nan yon dokiman ki gen vèsyon 1. Si yon lòt moun tou edite yon dokiman ak vèsyon 1 epi li soumèt chanjman devan nou, lè sa a ES p ap aksepte chanjman nou yo, paske li estoke dokiman an ak vèsyon 2.
Kle _source gen dokiman ke nou endèks la. ES pa sèvi ak valè sa a pou operasyon rechèch paske Endis yo itilize pou rechèch. Pou ekonomize espas, ES estoke yon dokiman sous konprese. Si nou sèlman bezwen id la, epi yo pa tout dokiman sous la, Lè sa a, nou ka enfim depo sous.
Si nou pa bezwen plis enfòmasyon, nou ka jwenn sèlman sa ki nan _source:
curl -XGET "$ES_URL/blog/post/1/_source?pretty"{
"title" : "Веселые котята",
"content" : "<p>Смешная история про котят<p>",
"tags" : [ "котята", "смешная история" ],
"published_at" : "2014-09-12T20:44:42+00:00"
}
Ou kapab tou chwazi sèlman sèten jaden:
# извлечем только поле title
curl -XGET "$ES_URL/blog/post/1?_source=title&pretty"{
"_index" : "blog",
"_type" : "post",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"title" : "Веселые котята"
}
}Ann endèks kèk pòs plis epi kouri demann ki pi konplèks.
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"
}'Triye
# найдем последний пост по дате публикации и извлечем поля 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 ]
} ]
}
}Nou te chwazi dènye pòs la. size limite kantite dokiman yo dwe bay. total montre kantite total dokiman ki koresponn ak demann lan. sort nan pwodiksyon an gen yon etalaj de nonm antye ki fè klasman. Moun sa yo. dat la te konvèti nan yon nonb antye relatif. Ou ka jwenn plis enfòmasyon sou klasman nan .
Filtè ak demann
ES depi vèsyon 2 pa fè distenksyon ant filtè ak demann, olye .
Yon kontèks rechèch diferan de yon kontèks filtre paske rechèch la jenere yon _score epi li pa nan kachèt. Mwen pral montre w kisa _score ye pita.
Filtre pa dat
Nou itilize demann lan nan kontèks filtre:
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'Filtre pa tags
Nou itilize pou chèche idantifikasyon dokiman ki gen yon mo bay:
# найдем все документы, в поле 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" : [ "котята" ]
}
} ]
}
}Rechèch tèks konplè
Twa nan dokiman nou yo genyen sa ki annapre yo nan domèn kontni an:
<p>Смешная история про котят<p><p>Смешная история про щенков<p><p>Душераздирающая история про бедного котенка с улицы<p>
Nou itilize pou chèche idantifikasyon dokiman ki gen yon mo bay:
# 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
} ]
}
}Sepandan, si nou chache "istwa" nan jaden contenu, nou p'ap jwenn anyen, paske Endèks la gen sèlman mo orijinal yo, pa tij yo. Yo nan lòd yo fè yon rechèch-wo kalite, ou bezwen konfigirasyon analizè a.
Jaden _score montre . Si demann lan egzekite nan yon kontèks filtre, Lè sa a, valè _score a ap toujou egal a 1, ki vle di yon match konplè ak filtè a.
Analisè yo
yo bezwen konvèti tèks sous la nan yon seri siy.
Analizè yo konpoze de youn ak plizyè opsyonèl . Tokenizer ka anvan pa plizyè . Tokenizers kraze fisèl sous la nan siy, tankou espas ak karaktè ponktiyasyon. TokenFilter ka chanje siy, efase oswa ajoute nouvo, pou egzanp, kite sèlman tij mo a, retire prepozisyon, ajoute sinonim. CharFilter - chanje tout fisèl sous la, pou egzanp, koupe tags html.
ES gen plizyè . Pou egzanp, yon analizeur .
Ann pwofite epi ann wè ki jan analizè estanda ak Ris yo transfòme fisèl "Istwa komik sou ti chat":
# используем анализатор 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
} ]
}Analizè estanda a fann fisèl la an espas epi konvèti tout bagay an minuskil, analizè Ris la retire mo ki pa enpòtan, konvèti li an minskil epi kite tij mo yo.
Ann wè ki Tokenizer, TokenFilters, CharFilters analizeur Ris la itilize:
{
"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 отсутствуют */
}
}
}Ann dekri analizè nou an ki baze sou Ris, ki pral koupe tags html. Ann rele li default, paske yon analizeur ki gen non sa a pral itilize pa default.
{
"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"
]
}
}
}Premyèman, tout etikèt HTML yo pral retire nan fisèl sous la, Lè sa a, estanda tokenizer la pral divize l 'nan marqueur, marqueur ki kapab lakòz yo ap deplase nan miniskil, mo ensiyifyan yo pral retire, ak marqueur ki rete yo ap rete tij la nan mo a.
Kreye yon endèks
Pi wo a nou dekri analizè default la. Li pral aplike nan tout jaden fisèl. Pòs nou an gen yon seri de tags, kidonk tag yo pral trete pa analizè a tou. Paske Nou ap chèche pòs pa matche egzak nan yon tag, Lè sa a, nou bezwen enfim analiz pou jaden an tags.
Ann kreye yon endèks blog2 ak yon analizeur ak kat, nan ki analiz la nan jaden tags la enfim:
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"
}
}
}
}
}'Ann ajoute menm 3 pòs yo nan endèks sa a (blog2). Mwen pral omisyon pwosesis sa a paske... li sanble ak ajoute dokiman nan endèks blog la.
Rechèch tèks konplè ak sipò ekspresyon
Ann pran yon gade nan yon lòt kalite demann:
# найдем документы, в которых встречается слово 'истории'
# 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"
]
}
}
}'Paske Nou ap itilize yon analizeur ak tij Ris, Lè sa a, demann sa a pral retounen tout dokiman, byenke yo sèlman gen mo 'istwa'.
Demann lan ka genyen karaktè espesyal, pa egzanp:
""fried eggs" +(eggplant | potato) -frittata"Sentaks demann:
+ 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 поста про котиковReferans
PS
Si w enterese nan atik-leson sa yo, si w gen lide pou nouvo atik oswa si w gen pwopozisyon pou koperasyon, m ap kontan resevwa yon mesaj pèsonèl oswa pa imèl nan m.kuzmin+habr@darkleaf.ru.
Sous: www.habr.com
