Az Elasticsearch egy json rest api-val rendelkező keresőmotor, amely Lucene-t használ, és Java nyelven íródott. A motor összes előnyének leírása a következő címen érhető el hivatalos honlapján. A következőkben az Elasticsearch-ra ES-ként fogunk hivatkozni.
Hasonló motorokat használnak a dokumentum-adatbázisban végzett összetett keresésekhez. Például keresés a nyelv morfológiájának figyelembevételével vagy földrajzi koordináták alapján.
Ebben a cikkben az ES alapjairól fogok beszélni a blogbejegyzések indexelésének példáján. Megmutatom, hogyan szűrhet, rendezhet és kereshet dokumentumok között.
Annak érdekében, hogy ne függjek az operációs rendszertől, minden kérést az ES-hez küldök a CURL használatával. A google chrome-hoz is van egy bővítmény, az úgynevezett értelemben.
A szöveg hivatkozásokat tartalmaz a dokumentációra és más forrásokra. A végén hivatkozások találhatók a dokumentáció gyors eléréséhez. Az ismeretlen kifejezések definíciói itt találhatók szószedetek.
Telepítés
Ehhez először Java-ra van szükségünk. Fejlesztők ajánlani telepítse a Java 8 frissítés 20-nál vagy a Java 7 frissítés 55-nél újabb Java-verziókat.
# Добавим документ 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 automatikusan létrejön index blog és típus hozzászólás. Feltételes analógiát vonhatunk le: az index egy adatbázis, a típus pedig egy táblázat ebben az adatbázisban. Minden típusnak megvan a maga sémája − térképészet, akárcsak egy relációs táblázat. A leképezés automatikusan generálódik a dokumentum indexelésekor:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"
A szerver válaszában hozzáadtam az indexelt dokumentum mezőinek értékeit a megjegyzésekhez:
Érdemes megjegyezni, hogy az ES nem tesz különbséget egyetlen érték és egy értéktömb között. Például a címmező egyszerűen egy címet tartalmaz, a címkék mező pedig egy karakterlánc tömböt tartalmaz, bár ezek a leképezésben ugyanúgy vannak ábrázolva.
A térképezésről később még beszélünk.
kérelmek
Dokumentum lekérése az azonosítója alapján:
# извлечем документ с id 1 типа post из индекса blog
curl -XGET "$ES_URL/blog/post/1?pretty"
Új kulcsok jelentek meg a válaszban: _version и _source. Általában minden billentyűvel kezdődik _ hivatalosnak minősülnek.
kulcs _version a dokumentum verzióját mutatja. Az optimista zárszerkezet működéséhez szükséges. Például egy 1-es verziójú dokumentumot szeretnénk módosítani. Beküldjük a módosított dokumentumot, és jelezzük, hogy ez egy 1-es verziójú dokumentum szerkesztése. Ha valaki más is szerkesztett egy 1-es verziójú dokumentumot, és módosításokat nyújtott be előttünk, akkor ES nem fogadja el a változtatásainkat, mert a 2-es verziójú dokumentumot tárolja.
kulcs _source tartalmazza az általunk indexelt dokumentumot. Az ES nem használja ezt az értéket a keresési műveletekhez, mert A kereséshez indexeket használnak. A helytakarékosság érdekében az ES tömörített forrásdokumentumot tárol. Ha csak az azonosítóra van szükségünk, és nem a teljes forrásdokumentumra, akkor letilthatjuk a forrástárolást.
Ha nincs szükségünk további információra, akkor csak a _source tartalmát kaphatjuk meg:
curl -XPUT "$ES_URL/blog/post/3" -d'
{
"title": "Как у меня появился котенок",
"content": "<p>Душераздирающая история про бедного котенка с улицы<p>",
"tags": [
"котята"
],
"published_at": "2014-07-21T20:44:42+00:00"
}'
osztályozás
# найдем последний пост по дате публикации и извлечем поля title и published_at
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"size": 1,
"_source": ["title", "published_at"],
"sort": [{"published_at": "desc"}]
}'
Az utolsó bejegyzést választottuk. size korlátozza a kiadandó dokumentumok számát. total a kérelemnek megfelelő dokumentumok teljes számát mutatja. sort a kimenetben egész számok tömbjét tartalmazza, amelyek alapján a rendezés végrehajtódik. Azok. a dátum egész számra lett konvertálva. A válogatásról bővebb információt itt talál dokumentáció.
Szűrők és lekérdezések
Az ES a 2. verzió óta nem tesz különbséget a szűrők és a lekérdezések között bevezetik a kontextusok fogalmát.
A lekérdezési kontextus abban különbözik a szűrőkontextustól, hogy a lekérdezés _score értéket generál, és nem kerül gyorsítótárba. Később megmutatom, mi az _score.
Szűrés dátum szerint
Használjuk a kérést hatótávolság szűrővel összefüggésben:
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'
Szűrés címkék szerint
Használjuk kifejezés lekérdezés adott szót tartalmazó dokumentumazonosítók kereséséhez:
# найдем все документы, в поле tags которых есть элемент 'котята'
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": [
"title",
"tags"
],
"filter": {
"term": {
"tags": "котята"
}
}
}'
Ha azonban a tartalom mezőben „történetekre” keresünk, nem találunk semmit, mert Az index csak az eredeti szavakat tartalmazza, a töveket nem. A jó minőségű keresés érdekében konfigurálnia kell az analizátort.
Mező _score mutatja relevanciáját. Ha a kérést szűrőkontextusban hajtják végre, akkor a _score értéke mindig 1 lesz, ami azt jelenti, hogy a szűrő teljes egyezést mutat.
Elemzők
Elemzők szükségesek a forrásszöveg tokenek halmazává alakításához.
Az elemzők egyből állnak Tokenizátor és több választható TokenFilters. A Tokenizert több is megelőzheti CharFilters. A tokenizálók a forráskarakterláncot tokenekre, például szóközökre és írásjelekre bontják. A TokenFilter módosíthatja a tokeneket, törölhet vagy újakat adhat hozzá, például csak a szó tőjét hagyhatja meg, eltávolíthatja az elöljárókat, szinonimákat adhat hozzá. CharFilter - megváltoztatja a teljes forráskarakterláncot, például kivágja a html címkéket.
Használjuk ki api és nézzük meg, hogyan alakítják át a szabványos és az orosz elemzők a „Vicces történetek a cicákról” sztringet:
# используем анализатор 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"
A szabványos elemző szóközökkel osztotta fel a karakterláncot, és mindent kisbetűre konvertált, az orosz elemző eltávolította a lényegtelen szavakat, kisbetűvé alakította, és elhagyta a szavak szárát.
Lássuk, melyik Tokenizer-t, TokenFilters-t, CharFilters-t használja az orosz analizátor:
Leírjuk az orosz alapú elemzőnket, amely kivágja a html címkéket. Nevezzük alapértelmezettnek, mert alapértelmezés szerint egy ilyen nevű elemzőt használ a rendszer.
Először az összes HTML tag eltávolításra kerül a forráskarakterláncból, majd a tokenizer szabvány tokenekre bontja, az így kapott tokenek kisbetűre kerülnek, a jelentéktelen szavak eltávolításra kerülnek, a fennmaradó tokenek pedig a szó törzse maradnak.
Index létrehozása
Fentebb leírtuk az alapértelmezett analizátort. Ez az összes karakterlánc mezőre vonatkozik. Posztunk egy sor címkét tartalmaz, így a címkéket is feldolgozza az elemző. Mert A bejegyzéseket pontos egyezés alapján keressük egy címkével, majd le kell tiltanunk a címkék mező elemzését.
Készítsünk egy index blog2-t elemzővel és leképezéssel, amelyben a címkék mező elemzése le van tiltva:
Adjuk hozzá ugyanazt a 3 bejegyzést ehhez az indexhez (blog2). Ezt a folyamatot kihagyom, mert... hasonló a dokumentumok blog indexhez való hozzáadásához.
Teljes szöveges keresés kifejezés támogatással
Nézzünk egy másik típusú kérelmet:
# найдем документы, в которых встречается слово 'истории'
# 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"
]
}
}
}'
Mert Orosz eredetű elemzőt használunk, akkor ez a kérés minden dokumentumot visszaad, bár ezek csak az „előzmények” szót tartalmazzák.
A kérés speciális karaktereket tartalmazhat, például:
""fried eggs" +(eggplant | potato) -frittata"
Szintaxis kérése:
+ 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 поста про котиков
Ha érdeklik a hasonló cikkek-leckék, ötletei vannak új cikkekre, vagy együttműködési javaslataik vannak, szívesen fogadok üzenetet személyes üzenetben vagy e-mailben [e-mail védett].