Bażi ta' Elasticsearch

Elasticsearch hija magna tat-tiftix b'json rest api, li tuża Lucene u miktuba bil-Java. Deskrizzjoni tal-vantaġġi kollha ta 'din il-magna hija disponibbli fuq websajt uffiċjali. F'dak li ġej se nirreferu għal Elasticsearch bħala ES.

Magni simili jintużaw għal tfittxijiet kumplessi f'database ta' dokumenti. Pereżempju, fittex b'kont meħud tal-morfoloġija tal-lingwa jew fittex bil-koordinati ġeografiċi.

F'dan l-artikolu ser nitkellem dwar il-baŜi ta 'ES billi tuża l-eżempju ta' indiċjar ta 'postijiet tal-blog. Ser nuruk kif tiffiltra, issortja u tfittex dokumenti.

Sabiex ma niddependix fuq is-sistema operattiva, se nagħmel it-talbiet kollha lil ES billi tuża CURL. Hemm ukoll plugin għall-google chrome imsejjaħ sens.

It-test fih links għal dokumentazzjoni u sorsi oħra. Fl-aħħar hemm links għal aċċess rapidu għad-dokumentazzjoni. Definizzjonijiet ta’ termini mhux familjari jistgħu jinstabu fi glossarji.

Installazzjoni ES

Biex nagħmlu dan, l-ewwel għandna bżonn Java. Iżviluppaturi jirrakkomanda installa verżjonijiet Java aktar ġodda minn Java 8 aġġornament 20 jew Java 7 aġġornament 55.

Id-distribuzzjoni ES hija disponibbli fuq websajt tal-iżviluppatur. Wara li tħoll l-arkivju trid tmexxi bin/elasticsearch. Disponibbli wkoll pakketti għal apt u yum. Hemm immaġni uffiċjali għal docker. Aktar dwar l-installazzjoni.

Wara l-installazzjoni u t-tnedija, ejja niċċekkjaw il-funzjonalità:

# для удобства запомним адрес в переменную
#export ES_URL=$(docker-machine ip dev):9200
export ES_URL=localhost:9200

curl -X GET $ES_URL

Se nirċievu xi ħaġa bħal din:

{
  "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"
}

Indiċjar

Ejja nżidu post għal 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"
}'

rispons tas-server:

{
  "_index" : "blog",
  "_type" : "post",
  "_id" : "1",
  "_version" : 1,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : false
}

ES maħluqa awtomatikament indiċi blog u Tip post. Nistgħu nfasslu analoġija kondizzjonali: indiċi huwa database, u tip huwa tabella f'din id-database. Kull tip għandu l-iskema tiegħu stess - immappjar, bħal tabella relazzjonali. L-immappjar jiġi ġġenerat awtomatikament meta d-dokument jiġi indiċjat:

# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"

Fir-rispons tas-server, żidt il-valuri tal-oqsma tad-dokument indiċjat fil-kummenti:

{
  "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"
          }
        }
      }
    }
  }
}

Ta 'min jinnota li ES ma jiddifferenzjax bejn valur wieħed u firxa ta' valuri. Pereżempju, il-qasam tat-titlu sempliċement fih titolu, u l-qasam tat-tikketti fih firxa ta 'kordi, għalkemm huma rappreżentati bl-istess mod fl-immappjar.
Nitkellmu aktar dwar l-immappjar aktar tard.

Talbiet

L-irkupru ta' dokument bl-id tiegħu:

# извлечем документ с 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"
  }
}

Ċwievet ġodda dehru fit-tweġiba: _version и _source. B'mod ġenerali, iċ-ċwievet kollha li jibdew _ huma kklassifikati bħala uffiċjali.

Ewlenin _version turi l-verżjoni tad-dokument. Huwa meħtieġ biex il-mekkaniżmu ta 'qfil ottimist jaħdem. Pereżempju, irridu nbiddlu dokument li għandu l-verżjoni 1. Aħna nissottomettu d-dokument mibdul u nindikaw li din hija editjar ta’ dokument bil-verżjoni 1. Jekk xi ħadd ieħor editja wkoll dokument bil-verżjoni 1 u ressaq bidliet quddiemna, allura ES mhux se jaċċetta l-bidliet tagħna, għaliex jaħżen id-dokument bil-verżjoni 2.

Ewlenin _source fih id-dokument li indiċjajna. ES ma jużax dan il-valur għal operazzjonijiet ta' tfittxija għax L-indiċijiet jintużaw għat-tiftix. Biex tiffranka l-ispazju, ES jaħżen dokument sors kompressat. Jekk għandna bżonn biss l-id, u mhux id-dokument tas-sors kollu, allura nistgħu tiddiżattiva l-ħażna tas-sors.

Jekk m'għandniex bżonn informazzjoni addizzjonali, nistgħu niksbu biss il-kontenut ta' _source:

curl -XGET "$ES_URL/blog/post/1/_source?pretty"
{
  "title" : "Веселые котята",
  "content" : "<p>Смешная история про котят<p>",
  "tags" : [ "котята", "смешная история" ],
  "published_at" : "2014-09-12T20:44:42+00:00"
}

Tista' wkoll tagħżel ċerti oqsma biss:

# извлечем только поле title
curl -XGET "$ES_URL/blog/post/1?_source=title&pretty"
{
  "_index" : "blog",
  "_type" : "post",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "Веселые котята"
  }
}

Ejja indiċi ftit aktar postijiet u mexxi mistoqsijiet aktar kumplessi.

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"
}'

Issortja

# найдем последний пост по дате публикации и извлечем поля 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 ]
    } ]
  }
}

Għażilna l-aħħar post. size jillimita n-numru ta' dokumenti li għandhom jinħarġu. total juri n-numru totali ta’ dokumenti li jaqblu mat-talba. sort fl-output fih firxa ta 'numri interi li bihom issir issortjar. Dawk. id-data ġiet konvertita għal numru sħiħ. Aktar informazzjoni dwar l-għażla tista’ ssibha fi dokumentazzjoni.

Filtri u mistoqsijiet

ES peress li l-verżjoni 2 ma tiddistingwix bejn filtri u mistoqsijiet, minflok jiġi introdott il-kunċett tal-kuntesti.
Kuntest ta' mistoqsija huwa differenti minn kuntest ta' filtru peress li l-mistoqsija tiġġenera _score u mhix fil-cache. Ser nuruk x'inhu _score aktar tard.

Iffiltra skond id-data

Aħna nużaw it-talba Firxa fil-kuntest tal-filtru:

# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
  "filter": {
    "range": {
      "published_at": { "gte": "2014-09-01" }
    }
  }
}'

Iffiltra mit-tikketti

Aħna nużaw mistoqsija fit-terminu biex tfittex ids tad-dokumenti li fihom kelma partikolari:

# найдем все документы, в поле 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" : [ "котята" ]
      }
    } ]
  }
}

Tfittxija bit-test sħiħ

Tlieta mid-dokumenti tagħna fihom dan li ġej fil-qasam tal-kontenut:

  • <p>Смешная история про котят<p>
  • <p>Смешная история про щенков<p>
  • <p>Душераздирающая история про бедного котенка с улицы<p>

Aħna nużaw taqbila mistoqsija biex tfittex ids tad-dokumenti li fihom kelma partikolari:

# 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
    } ]
  }
}

Madankollu, jekk infittxu "stejjer" fil-qasam tal-kontenut, ma nsibu xejn, għaliex L-indiċi fih biss il-kliem oriġinali, mhux iz-zkuk tagħhom. Sabiex tagħmel tfittxija ta 'kwalità għolja, għandek bżonn tikkonfigura l-analizzatur.

Qasam _score turina rilevanza. Jekk it-talba titwettaq f'kuntest ta 'filtru, allura l-valur _score dejjem ikun ugwali għal 1, li jfisser taqbila sħiħa mal-filtru.

Analizzaturi

Analizzaturi huma meħtieġa biex jikkonvertu t-test sors f'sett ta' tokens.
L-analizzaturi jikkonsistu f'wieħed Tokenizer u diversi fakultattivi TokenFilters. Tokenizer jista 'jkun preċedut minn diversi CharFilters. Tokenizers ikissru s-sekwenza tas-sors f'tokens, bħal spazji u karattri ta' punteġġjatura. TokenFilter jista 'jbiddel tokens, iħassar jew iżid oħrajn ġodda, pereżempju, iħalli biss iz-zokk tal-kelma, neħħi prepożizzjonijiet, żid sinonimi. CharFilter - jibdel is-sekwenza tas-sors kollu, pereżempju, jaqta 'tags html.

ES għandha diversi analizzaturi standard. Per eżempju, analizzatur Russu.

Ejja nieħdu vantaġġ api u ejja naraw kif l-analizzaturi standard u Russi jittrasformaw is-sekwenza "Stejjer umoristiċi dwar qtates":

# используем анализатор 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
  } ]
}

L-analizzatur standard qasam is-sekwenza bi spazji u kkonverti kollox f'ittri żgħar, l-analizzatur Russu neħħa kliem mhux importanti, ikkonvertih f'ittri żgħar u ħalla z-zokk tal-kliem.

Ejja naraw liema Tokenizer, TokenFilters, CharFilters juża l-analizzatur Russu:

{
  "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 отсутствуют */
    }
  }
}

Ejja niddeskrivu l-analizzatur tagħna bbażat fuq ir-Russu, li se jaqta 'tags html. Ejja nsejħulha default, għaliex analizzatur b'dan l-isem se jintuża awtomatikament.

{
  "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"
      ]
    }
  }
}

L-ewwel, it-tikketti HTML kollha se jitneħħew mis-sekwenza tas-sors, allura l-istandard tokenizer se jaqsamha f'tokens, it-tokens li jirriżultaw se jimxu f'ittri żgħar, kliem insinifikanti se jitneħħew, u t-tokens li jifdal jibqgħu l-zokk tal-kelma.

Ħolqien ta' Indiċi

Hawn fuq aħna ddeskrivejna l-analizzatur default. Se tapplika għall-oqsma kollha ta' string. Il-kariga tagħna fiha firxa ta 'tikketti, għalhekk it-tikketti se jiġu pproċessati wkoll mill-analizzatur. Għax Qegħdin infittxu karigi b'taqbila eżatta ma' tikketta, imbagħad irridu tiddiżattiva l-analiżi għall-qasam tat-tikketti.

Ejja noħolqu indiċi blog2 b'analizzatur u mapping, li fih l-analiżi tal-qasam tat-tikketti hija diżattivata:

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"
        }
      }
    }
  }
}'

Ejja nżidu l-istess 3 postijiet ma 'dan l-indiċi (blog2). Se nħalli dan il-proċess għax... huwa simili għaż-żieda ta 'dokumenti mal-indiċi tal-blog.

Tfittxija bit-test sħiħ b'appoġġ għall-espressjoni

Ejja nagħtu ħarsa lejn tip ieħor ta 'talba:

# найдем документы, в которых встречается слово 'истории'
# 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"
      ]
    }
  }
}'

Għax Qegħdin nużaw analizzatur bi stemming Russu, allura din it-talba tirritorna d-dokumenti kollha, għalkemm fihom biss il-kelma 'storja'.

It-talba jista' jkun fiha karattri speċjali, pereżempju:

""fried eggs" +(eggplant | potato) -frittata"

Sintassi tat-talba:

+ 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 поста про котиков

referenzi

PS

Jekk inti interessat f'dawn l-artikoli-lezzjonijiet, għandek ideat għal artikli ġodda jew għandek proposti għal kooperazzjoni, inkun kuntent li nirċievi messaġġ f'messaġġ personali jew bil-posta m.kuzmin+habr@darkleaf.ru.

Sors: www.habr.com