Elasticsearch ass eng Sichmotor mat json rest api, benotzt Lucene a geschriwwen op Java. Eng Beschreiwung vun all de Virdeeler vun dësem Motor ass verfügbar op offizieller Websäit. An deem folgend wäerte mir op Elasticsearch als ES bezeechnen.
Ähnlech Motore gi fir komplex Recherchen an enger Dokumentdatenbank benotzt. Zum Beispill, Sich ënner Beuechtung vun der Morphologie vun der Sprooch oder Sich no Geo Koordinaten.
An dësem Artikel wäert ech iwwer d'Basis vun ES schwätzen andeems Dir d'Beispill vun der Indexéierung vu Blogposte benotzt. Ech weisen Iech wéi Dir Dokumenter filtert, sortéiert a sicht.
Fir net vum Betribssystem ofhänken, wäert ech all Ufro un ES mat CURL maachen. Et gëtt och e Plugin fir Google Chrome genannt Sënn.
Den Text enthält Linken op Dokumentatioun an aner Quellen. Um Enn ginn et Linken fir séier Zougang zu der Dokumentatioun. Definitioune vun onbekannte Begrëffer kënnen an Glossarien.
Installatioun vun ES
Fir dëst ze maachen, brauche mir als éischt Java. Entwéckler empfeelen installéiere Java Versioune méi nei wéi Java 8 Update 20 oder Java 7 Update 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 automatesch erstallt Index blog an Typ posten. Mir kënnen eng bedingt Analogie zéien: en Index ass eng Datebank, an en Typ ass eng Tabell an dëser Datebank. All Typ huet säin eegene Schema - Conclusiounen, grad wéi e relationalen Dësch. Mapping gëtt automatesch generéiert wann d'Dokument indexéiert ass:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"
An der ServerÄntwert hunn ech d'Wäerter vun de Felder vum indexéierten Dokument an de Kommentarer bäigefüügt:
Et ass derwäert ze notéieren datt ES net ënnerscheet tëscht engem eenzege Wäert an enger Rei vu Wäerter. Zum Beispill enthält den Titelfeld einfach en Titel, an d'Tagsfeld enthält eng Array vu Strings, obwuel se an der selwechter Aart a Mapping vertruede sinn.
Mir schwätze méi iwwer d'Mapping spéider.
Demanden
En Dokument duerch seng ID zréckzéien:
# извлечем документ с id 1 типа post из индекса blog
curl -XGET "$ES_URL/blog/post/1?pretty"
Nei Schlësselen erschéngen an der Äntwert: _version и _source. Am Allgemengen, all Schlëssel ugefaange mat _ ginn als offiziell klasséiert.
Schlëssel _version weist d'Dokumentversioun. Et ass néideg fir den optimistesche Sperrmechanismus ze schaffen. Zum Beispill wëlle mir en Dokument änneren, deen d'Versioun 1 huet. Mir stellen dat geännert Dokument of a weisen datt dëst eng Ännerung vun engem Dokument mat der Versioun 1 ass. Wann een aneren och en Dokument mat der Versioun 1 geännert huet an Ännerunge virun eis presentéiert huet, dann ES wäert eis Ännerungen net akzeptéieren, well et späichert d'Dokument mat der Versioun 2.
Schlëssel _source enthält dat Dokument dat mir indexéiert hunn. ES benotzt dëse Wäert net fir Sich Operatiounen well Indexe gi benotzt fir ze sichen. Fir Plaz ze spueren, späichert ES e kompriméierte Quelldokument. Wa mir nëmmen d'ID brauchen, an net de ganze Quelldokument, da kënne mir d'Quellspäicherung auszeschalten.
Wa mir keng zousätzlech Informatioun brauchen, kënne mir nëmmen den Inhalt vun _source kréien:
curl -XPUT "$ES_URL/blog/post/3" -d'
{
"title": "Как у меня появился котенок",
"content": "<p>Душераздирающая история про бедного котенка с улицы<p>",
"tags": [
"котята"
],
"published_at": "2014-07-21T20:44:42+00:00"
}'
Zortéieren
# найдем последний пост по дате публикации и извлечем поля title и published_at
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"size": 1,
"_source": ["title", "published_at"],
"sort": [{"published_at": "desc"}]
}'
Mir hunn de leschte Post gewielt. size limitéiert d'Zuel vun den Dokumenter déi ausgestallt ginn. total weist d'Gesamtzuel vun den Dokumenter, déi d'Ufro passen. sort am Ausgang enthält eng Rei vun ganz Zuelen, duerch déi d'Sortéierung duerchgefouert gëtt. Déi. den Datum gouf an eng ganz Zuel ëmgerechent. Méi Informatioun iwwer d'Sortéierung fannt Dir an Dokumentatioun.
Filteren an Ufroen
ES zënter Versioun 2 ënnerscheet net tëscht Filteren an Ufroen, amplaz d'Konzept vu Kontexter gëtt agefouert.
En Ufrokontext ënnerscheet sech vun engem Filterkontext an datt d'Ufro en _Score generéiert an net am Cache gëtt. Ech weisen Iech méi spéit wat _score ass.
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'
Filter no Tags
Mir benotzen Begrëff Ufro Sich no Dokument-IDen mat engem bestëmmte Wuert:
# найдем все документы, в поле tags которых есть элемент 'котята'
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": [
"title",
"tags"
],
"filter": {
"term": {
"tags": "котята"
}
}
}'
Wéi och ëmmer, wa mir no "Geschichten" am Inhaltsfeld sichen, fanne mir näischt, well Den Index enthält nëmmen déi originell Wierder, net hir Stämm. Fir eng qualitativ héichwäerteg Sich ze maachen, musst Dir den Analyser konfiguréieren.
Beräich _score weist Relevanz. Wann d'Ufro an engem Filterkontext ausgefouert gëtt, da wäert de _score Wäert ëmmer gläich 1 sinn, dat heescht e komplette Match zum Filter.
Analyséierer
Analyséierer sinn néideg fir de Quelltext an eng Rei vun Tokens ze konvertéieren.
Analysatoren besteet aus engem Tokenizer an e puer fakultativ TokenFilters. Tokenizer ka vun e puer virausgesat ginn CharFilters. Tokenizer briechen d'Quellstring an Tokens, wéi Plazen a Punktuatiounszeechen. TokenFilter kann Tokens änneren, läschen oder nei addéieren, zum Beispill nëmmen de Stamm vum Wuert verloossen, Präpositioune läschen, Synonyme derbäisetzen. CharFilter - ännert de ganze Quellstring, zum Beispill, schneid HTML-Tags aus.
Loosst eis profitéieren API a loosst eis kucken wéi d'Standard a russesch Analysatoren d'String "Komesch Geschichten iwwer Kitten" transforméieren:
# используем анализатор 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"
De Standard Analyser huet d'String duerch Plazen opgedeelt an alles an kleng Buschtawen ëmgewandelt, de russesche Analyser huet onwichteg Wierder ewechgeholl, an kleng Buschtawen ëmgewandelt an de Stamm vun de Wierder verlooss.
Loosst eis kucken wéi eng Tokenizer, TokenFilters, CharFilters de russesche Analyser benotzt:
Loosst eis eisen Analyser op Russesch beschreiwen, deen HTML-Tags ausschneiden. Loosst eis et Standard nennen, well en Analyser mat dësem Numm gëtt Par défaut benotzt.
Als éischt ginn all HTML-Tags aus der Quellstring geläscht, da wäert den Tokenizer-Standard et an Tokens opdeelen, déi resultéierend Tokens ginn op kleng Buschtawen réckelen, onbedeitend Wierder ginn ewechgeholl, an déi verbleiwen Tokens bleiwen de Stamm vum Wuert.
En Index erstellen
Uewen hu mir de Standardanalysator beschriwwen. Et gëlt fir all Stringfelder. Eise Post enthält eng ganz Rëtsch vun Tags, sou datt d'Tags och vum Analysator veraarbecht ginn. Well Mir sichen no Posts no genaue Match zu engem Tag, da musse mir d'Analyse fir d'Tagsfeld auszeschalten.
Loosst eis en Index Blog2 mat engem Analysator a Mapping erstellen, an deem d'Analyse vum Tagsfeld behënnert ass:
Loosst eis déi selwecht 3 Posts an dësen Index addéieren (blog2). Ech wäert dëse Prozess ausgoen well ... et ass ähnlech wéi Dokumenter an de Blogindex bäizefügen.
Voll Text Sich mat Ausdrock Ënnerstëtzung
Loosst eis eng aner Aart vun Ufro kucken:
# найдем документы, в которых встречается слово 'истории'
# 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"
]
}
}
}'
Well Mir benotzen en Analyser mat russescher Stemmung, da wäert dës Ufro all Dokumenter zréckginn, obwuel se nëmmen d'Wuert "Geschicht" enthalen.
D'Ufro kann speziell Zeechen enthalen, zum Beispill:
""fried eggs" +(eggplant | potato) -frittata"
Ufro Syntax:
+ 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 поста про котиков
Wann Dir un ähnlechen Artikel-Lektioune interesséiert sidd, Iddie fir nei Artikelen hutt oder Propositioune fir Zesummenaarbecht hutt, da wäert ech frou e Message an enger perséinlecher Noriicht oder per E-Mail ze kréien [Email geschützt].