Marcin
Lewandowski
Marcin
Lewandowski
Marcin
Lewandowski
Marcin
Lewandowski
09:00 do 09:15 - Rozpoczęcie dnia, sprawy organizacyjne
09:15 do 10:45 - Blok szkoleniowy
10:45 do 11.00 - Przerwa kawowa ( 15 min. )
11:00 do 13:00 - Blok szkoleniowy
13:00 do 13:45 - Przerwa obiadowa ( 45 min. )
13:45 do 14:45 - Blok szkoleniowy
14:45 do 15:00 - Przerwa kawowa ( 15 min. )
15:00 do 16:00 - Blok szkoleniowy
16:00 do 17:00 - Praca indywidualna uczestników
Marcin
Lewandowski
1. Introduction to Elasticsearch
2. Writing Search Queries
3. Performing Text Analysis
4. Defining Mappings
5. Expanding Your Searches
6. The Distributed Model
7. Manipulating Search Results
8. Performing Aggregations
9. Handling Data Relationships
10. Summary and Conclusion
Elasticsearch
Logstash
Kibana
Beats
X Pack
Elastic cloud
Odpowiedzialny za bezpieczeństwo danych.
Alternatywy
Lekka aplikacja napisana w Go służąca do przesyłania danych specjalny przygotowanych pod ElasticSearch.
Najważniejsze cech:
Dostępne Beats
SERWER
( cluster, node, shard, replica )
DANE
( index, type, document )
NODE (węzeł)
CLUSTER (klaster)
SHARD / REPLICA
zbiór jednego lub więcej węzłów
pojedyncza instalacja serwera
do wersji 7
INDEX (indeks)
TYPE (typ)
sposób grupowania dokumentów
kolekcja dokumentów
DOCUMENT (dokument)
podstawowa jednostka indeksowania
DATABASE (baza danych)
TABLE (tabela)
RECORD (rekord / wiersz)
po wersji 7.x
INDEX (indeks)
kolekcja dokumentów
DOCUMENT (dokument)
podstawowa jednostka indeksowania
TABLE (tabela)
RECORD (rekord / wiersz)
Instalacja serwera
Zalogowanie na administratora
sudo su
Import klucza PGP
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
Instalacja pakietu apt-transport-https
sudo apt-get install apt-transport-https
Dodanie repozytorium z ElasticSearch
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list
Aktualizacja listy pakietów i instalacja Elasticsearch
sudo apt-get update && sudo apt-get install elasticsearch
Instalacja serwera
Sprawdzamy czy serwis wystartował
systemctl status elasticsearch.service
Startujemy serwis
systemctl start elasticsearch.service
Instalacja serwera
Instalacja Kibany
sudo apt-get install kibana
Dodajemy serwis do autostartu
systemctl enable kibana
Kibana
Startujemy serwis
systemctl start kibana
Sprawdzamy czy mamy dostęp do Kibany pod adresem
localhost:5601
Instalacja serwera
Docker
Instalacja Docker
apt-get install docker.io
Instalacja Docker Compose
apt-get install docker-compose
Wymagania:
Instalacja serwera
Wyszukujemy odpowiedni obraz na Docker Hub np.
Docker
Startujemy kontener
docker run -d -p 9201:9200 -p 5602:5601 nshou/elasticsearch-kibana
Sprawdzamy czy mamy dostęp do Kibany pod adresem
localhost:5602
Sprawdzamy czy kontener został uruchomiony
docker ps
Instalacja serwera
docker-compose.yml
Plik z konfiguracją środowiska testowego
version: '3'
services:
es:
image: nshou/elasticsearch-kibana
ports:
- "9201:9200"
- "5602:5601"
Instalacja serwera
docker-compose.yml
Uruchomienie środowiska
docker-compose up
Uruchomienie środowiska w tle
docker-compose up -d
Sprawdzenie uruchomionych kontenerów
docker ps
Zatrzymanie środowiska
ctrl + c
Zatrzymanie środowiska
docker-compose down
PUT shop
Dodajemy indeks
Odpowiedź
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "shop"
}
Kibana
CURL
curl -XPUT 'localhost:9200/shop'
Indeks istnieje
{
"error": {
"root_cause": [
{
"type": "resource_already_exists_exception",
"reason": "index [shop/BlQB1sKYTA6sV6KOpCp4cw] already exists",
"index_uuid": "BlQB1sKYTA6sV6KOpCp4cw",
"index": "shop"
}
],
"type": "resource_already_exists_exception",
"reason": "index [shop/BlQB1sKYTA6sV6KOpCp4cw] already exists",
"index_uuid": "BlQB1sKYTA6sV6KOpCp4cw",
"index": "shop"
},
"status": 400
}
Składnia
{
"error": "Incorrect HTTP method for uri [/shop] and method [POST], allowed: [GET, HEAD, DELETE, PUT]",
"status": 405
}
Sprawdzamy listę indeksów
Kibana
GET _stats
Odpowiedź
{
"_shards": {
...
},
"_all": {
...
},
"indices": {
"shop": {
...
}
}
}
CURL
curl -XGET 'localhost:9200/_stats?pretty'
Usuwanie indeksu
Kibana
DELETE shop
Odpowiedź
{
"acknowledged": true
}
CURL
curl -XDELETE 'localhost:9200/shop?pretty'
Lista indeksów
{
"_shards": {
...
},
"_all": {
...
},
"indices": {}
}
Indeks nie istnieje
{
"error": {
"root_cause": [
{
"type": "index_not_found_exception",
"reason": "no such index",
"resource.type": "index_or_alias",
"resource.id": "shop",
"index_uuid": "_na_",
"index": "shop"
}
],
"type": "index_not_found_exception",
"reason": "no such index",
"resource.type": "index_or_alias",
"resource.id": "shop",
"index_uuid": "_na_",
"index": "shop"
},
"status": 404
}
wielu typów w ramach jednego indeksu
tylko jeden typ w indeksie
rezygnacja z typów
POST shop/products
{
}
Dodajemy nowy typ
Kibana
curl -XPOST 'localhost:9200/shop/products?pretty' -d '{}'
CURL
{
"_index": "shop",
"_type": "products",
"_id": "9nCx-GYB4OAq-pq-3A1z",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
Odpowiedź
określa typy pól w dokumentach
GET shop/_mapping
Sprawdzamy mapping
Kibana
curl -XGET 'localhost:9200/shop/_mapping?pretty'
CURL
{
"shop" : {
"mappings" : {
}
}
}
Odpowiedź
dwie metody generowania
mapping generowany na podstawie przesyłanych dokumentów
mapping określa użytkownik przesyłając schemat mappingu
Dodajemy dokument do indeksu
Kibana
POST shop
{
"name": "Xiaomi Redmi 4X",
"price": 1200,
"category": "smartfon",
"creation_date": "2018-01-30"
}
Odpowiedź
{
"_index": "shop",
"_type": "products",
"_id": "BXDj-GYB4OAq-pq-SQ5Y",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
Dodajemy dokument do indeksu o określonym identyfikatorze
POST shop/1
{
"name": "Xiaomi Redmi 4X",
"price": 1200,
"category": "smartfon",
"creation_date": "2018-01-30"
}
Odpowiedź
{
"_index": "shop",
"_type": "products",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
Sprawdzamy automatycznie wygenerowany mapping
Kibana
GET shop/_mapping
"category": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"creation_date": {
"type": "date"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"price": {
"type": "long"
}
POST shop
{
"name": "Xiaomi Redmi 4X",
"price": 1200,
"category": "smartfon",
"creation_date": "2018-01-30"
}
Dodajemy produkt z typem float
Kibana
POST shop
{
"name": "Xiaomi Redmi 4X",
"price": 1199.99,
"category": "smartfon",
"creation_date": "2018-01-30"
}
GET shop/_mapping
Sprawdzamy czy zmienił się mapping
...
"price": {
"type": "long"
}
Odpowiedź
Dodajemy produkt z nowym polem float
POST shop
{
"name": "Xiaomi Redmi 4X",
"price": 1500.00,
"promotion": 1199.99,
"category": "smartfon",
"creation_date": "2018-01-30"
}
GET shop/_mapping
Sprawdzamy czy zmienił się mapping
...
"promotion": {
"type": "float"
}
Odpowiedź
PUT shop
{
"mappings": {
"properties": {
... mapping ...
}
}
}
Definiujemy mapping
Usuwamy indeks
DELETE shop
PUT shop
{
"mappings": {
"properties": {
"category": {
"type": "text"
},
"creation_date": {
"type": "date"
},
"name": {
"type": "text"
},
"price": {
"type": "double"
}
}
}
}
Tworzymy indeks
Sprawdzamy mapping
GET shop/_mapping
"shop": {
"mappings": {
"properties": {
"category": {
"type": "text"
},
"creation_date": {
"type": "date"
},
"name": {
"type": "text"
},
"price": {
"type": "double"
}
}
}
}
( nested )
"manufacturer": {
"type": "nested",
"properties": {
... lista pól ...
}
}
Definicja pola nested
Dodajemy pole typu nested do indeksu
PUT shop/_mapping
{
"properties": {
"manufacturer": {
"properties": {
"id": {
"type": "integer",
"store": true,
"index": true
},
"name": {
"type": "text"
}
}
}
}
}
Aktualizujemy mapping
GET shop/_mapping
{
"shop": {
"mappings": {
"properties": {
"category": {
"type": "text"
},
"creation_date": {
"type": "date"
},
"manufacturer": {
"properties": {
"id": {
"type": "integer",
"store": true
},
"name": {
"type": "text"
}
}
},
"name": {
"type": "text"
},
"price": {
"type": "double"
}
}
}
}
}
Sprawdzamy modyfikacje
Proces dodawania do indeksu
analyzer: {
"char_filter": ["html_strip"],
"tokenizer": "standard",
"filter": ["lowercase"]
}
Testowanie poszczególnych elementów
GET /_analyze
{
"text": ["Xiaomi <strong>Redmi</strong> 4X"]
}
Do testów poszczególnych elementów używamy endpoint-u _analyze
char_filter
GET /_analyze
{
"char_filter": [
"html_strip"
],
"text": ["Xiaomi <strong>Redmi</strong> 4X"]
}
char_filter - HTML strip character filter
PUT test_char_filter
{
"settings": {
"analysis": {
"char_filter": {
"accept_strong": {
"type": "html_strip",
"escaped_tags": [
"strong"
]
}
}
}
}
}
Możliwa jest tworzenie własnych ustawień dla filtrów znaków.
GET /test_char_filter/_analyze
{
"char_filter": [
"accept_strong"
],
"text": ["Xiaomi <strong>Redmi</strong> 4X"]
}
mapping - Mapping Character Filter
Filtr mapowania znaków pozwala przypisać określonym znakom odpowiedniki.
GET /_analyze
{
"char_filter": [
{
"type": "mapping",
"mappings": [
"1 => jeden",
"2 => dwa"
]
}
],
"text": ["Akceptowane cyfry to: 1 lub 2"]
}
Zamiast wpisywania całego mapping-u ręcznie, możliwe jest zdefiniowanie go w pliku i podanie ścieżki do pliku. Robimy to w parametrze: mappings_path
mapping - Mapping Character Filter
Filtr mapowania znaków pozwala przypisać określonym znakom odpowiedniki.
GET /_analyze
{
"char_filter": [
{
"type": "mapping",
"mappings": [
"1 => jeden",
"2 => dwa"
]
}
],
"text": ["Akceptowane cyfry to: 1 lub 2"]
}
Zamiast wpisywania całego mapping-u ręcznie, możliwe jest zdefiniowanie go w pliku i podanie ścieżki do pliku. Robimy to w parametrze: mappings_path
pattern_replace - Pattern Replace Character Filter
Filtr wyrażeń regularnych.
GET /_analyze
{
"char_filter": [
{
"type": "pattern_replace",
"pattern": "(\\d+)",
"replacement": "$1 (cyfra)"
}
],
"text": ["Akceptowane cyfry to: 1 lub 2"]
}
Dostępne tokenizery
standard
GET /_analyze
{
"tokenizer": "standard",
"text": "Xiaomi Redmi 4X"
}
{
"tokens": [
{
"token": "Xiaomi",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "Redmi",
"start_offset": 7,
"end_offset": 12,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "4X",
"start_offset": 13,
"end_offset": 15,
"type": "<ALPHANUM>",
"position": 2
}
]
}
Tokenizer standardowy
Efekt działania
GET /_analyze
{
"tokenizer" : "standard",
"filter" : ["lowercase"],
"text" : "Xiaomi Redmi 4X"
}
lowercase
{
"tokens" : [
{
"token" : "xiaomi",
"start_offset" : 0,
"end_offset" : 6,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "redmi",
"start_offset" : 7,
"end_offset" : 12,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "4x",
"start_offset" : 13,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 2
}
]
}
Standard Tokenizer
Standard Token Filter, Lower Case Token Filter
Lower Case Tokenizer
Whitespace Tokenizer
Pattern Tokenizer
Lower Case Token Filter, Stop Token Filter
Standard Tokenizer
Lower Case Token Filter, ASCII Folding Token Filter, Stop Token Filter, Fingerprint Token Filter
Lower Case Tokenizer
dodaje obsługę stop words
zwraca dane wejściowe jako pojedynczy token
obsługują specyficznie każdy wspierany język
Dostępne analizery
Dostępne analizery
GET /_analyze
{
"analyzer": "standard",
"text": "Xiaomi Redmi 4X"
}
Analizer standardowy
Tworzymy własny analizer
{
"settings": {
"analysis": {
"analyzer": {
...
}
}
}
}
Struktura
Analizer
"my_analyzer": {
"type": "custom",
"char_filter": [
"html_strip"
],
"tokenizer": "standard",
"filter": [
"lowercase"
]
}
PUT shop/_settings
{
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": ["html_strip"],
"tokenizer": "standard",
"filter": ["lowercase"]
}
}
}
}
POST /shop/_close
POST /shop/_open
Zamykamy indeks
Otwieramy indeks
Testujemy stworzony analizer
GET /shop/_analyze
{
"analyzer": "standard",
"text": ["Xiaomi <strong>Redmi</strong> 4X"]
}
GET /shop/_analyze
{
"analyzer": "my_analyzer",
"text": ["Xiaomi <strong>Redmi</strong> 4X"]
}
{
"tokens": [
{
"token": "xiaomi",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "redmi",
"start_offset": 15,
"end_offset": 29,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "4x",
"start_offset": 30,
"end_offset": 32,
"type": "<ALPHANUM>",
"position": 2
}
]
}
{
"tokens": [
{
"token": "xiaomi",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "strong",
"start_offset": 8,
"end_offset": 14,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "redmi",
"start_offset": 15,
"end_offset": 20,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "strong",
"start_offset": 22,
"end_offset": 28,
"type": "<ALPHANUM>",
"position": 3
},
{
"token": "4x",
"start_offset": 30,
"end_offset": 32,
"type": "<ALPHANUM>",
"position": 4
}
]
}
brak analizy wyszukiwanej frazy
przed rozpoczęciem wyszukiwania fraza jest analizowana
Mapping
Dane testowe
Otwieramy poniższe linki i zapisujemy jako pliki Ctrl + S.
Nie zmieniamy nazwy plików ;)
Import indeksu
curl -XPUT 'http://127.0.0.1:9200' -H 'Content-Type: application/json' -d @movies_mapping_v1.txt
Import się nie powiedzie ze względu na pierwszą linię, którą trzeba usunąć PUT movies_v1.
Import danych
curl -XPOST 'http://127.0.0.1:9200/_bulk' -H 'Content-Type: application/json' --data-binary @movies_data-1.txt
Sprawdzamy czy dane znajdują się w indeksie
POST movies_v1/_search
{
...
"hits": {
"total": 20,
"max_score": 1,
"hits": [
{
"_index": "produkty",
"_type": "product",
"_id": "gpPNDGcBIwsD9fejqIT1",
"_score": 1,
"_source": {
"utworzono": "2018-08-23",
"nazwa": "iPad Pro",
"url": "ipad-pro",
"cena": 3500,
"producent": {
"name": "Apple",
"id": 2
},
"kategoria": "Tablety",
"opis": "Zamień komputer..."
}
},
]
}
}
Przeszukiwanie określonego pola ( Term )
Wyszukujemy frazę "zielona mila"
Wyszukujemy frazę "zielona"
GET movies_v1/_search
{
"query": {
"term": {
"title": "zielona mila"
}
}
}
GET produkty/_search
{
"query": {
"term": {
"title": "zielona"
}
}
}
Wyszukiwanie wielu fraz ( Terms )
Wyszukujemy frazę "zielona" lub "mila"
GET produkty/_search
{
"query": {
"terms": {
"nazwa": ["zielona", "mila"]
}
}
}
"hits" : [
{
"_score" : 1.0,
"_source" : {
"title" : "Zielona mila"
}
},
{
"_score" : 1.0,
"_source" : {
"title" : "8 Mila"
}
},
...
Prefix
Wyszukiwanie tokenów zaczynających się na "zielon"
GET movies_v1/_search
{
"query": {
"prefix": {
"nazwa": "zielon"
}
}
}
Ids
GET movies_v1/_search
{
"query": {
"ids": {
"values": [6836, 5573, 1359]
}
}
}
Wyszukiwanie dokumentów po ich identyfikatorze
Range
GET movies_v1/_search
{
"_source": ["title", "year"],
"query": {
"range": {
"year": {
"gte": 2010,
"lte": 2012
}
}
}
}
Wyszukiwanie dokumentów w ramach zdefiniowanego zakresu.
GET movies_v1/_search
{
"_source": ["title", "rate"],
"query": {
"range": {
"rate": {
"gte": 8
}
}
}
}
Fuzzy Query
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"fuzzy": {
"title": {
"value": "zielona"
}
}
}
}
Wykorzystuje odległość Levenshteina
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"term": {
"title": {
"value": "zielona"
}
}
}
}
7 wyników
16 wyników
Wildcard
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"wildcard": {
"title": {
"value": "?arr*"
}
}
}
}
Zapytanie umożliwiające elastyczne wyszukiwanie poprzez zastępowanie znaków znakami specjalnymi.
Znaki specjalne możliwe do wykorzystania:
* - zastępuje wiele znaków
? - zastępuje jeden znak
Regexp
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"regexp": {
"title": {
"value": "zie.*"
}
}
}
}
Wyszukiwanie oparte o wyrażenia regularne. Zapytanie bardzo zasobożerne i nie jest zalecane używanie tego na produkcji.
Wyszukiwanie w określonym polu
Wyszukiwanie frazy "zielona mila"
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"match": {
"title": {
"query": "zielona mila"
}
}
}
}
Match
zmiana operatora na AND
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"match": {
"title": {
"query": "zielona mila",
"operator": "and"
}
}
}
}
Wyszukiwanie w określonej kolejności
Wyszukiwanie frazy "harry potter"
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"match_phrase": {
"title": {
"query": "harry potter"
}
}
}
}
Match Phrase
dodanie operatora na sloop
GET movies_v1/_search
{
"_source": ["title"],
"query": {
"match_phrase": {
"title": {
"query": "harry sally",
"slop": 1
}
}
}
}
Wyszukiwanie frazy
"harry Hendersons"
GET movies_v1/_search
{
"_source": ["title", "title_org"],
"query": {
"multi_match": {
"fields": [
"title",
"title_org"
],
"query": "harry Hendersons"
}
}
}
Multi Match
Przeszukiwanie wielu pól jednocześnie.
GET movies_v1/_search
{
"_source": ["title", "title_org"],
"query": {
"multi_match": {
"fields": [
"title^3",
"title_org"
],
"query": "harry Hendersons"
}
}
}
Boost na polu title
GET movies_v1/_search
{
"_source": ["title", "title_org"],
"query": {
"nested": {
"path": "genres",
"query": {
"match": {
"genres.name": "komedia"
}
}
}
}
}
Nested
Struktura zapytania
GET produkty/_search
{
"query": {
"bool" : {
"must" : {},
"filter": {},
"must_not" : {},
"should" : {}
}
}
}
Wyszukujemy wszystkie produkty z kategorii "tablety"
bool - must
GET produkty/_search
{
"query": {
"bool": {
"must": {
"match": {
"kategoria": "tablety"
}
}
}
}
}
Wyszukujemy wszystkie produkty z kategorii "tablety" w przedziale cenowym od 1000 do 1500
bool - must
GET produkty/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"kategoria": "tablety"
}
},
{
"range": {
"cena": {
"gte": 1000,
"lte": 1500
}
}
}
]
}
}
}
Wyszukujemy wszystkie produkty z kategorii "tablety" bez wpływu na "_score"
Bool - filter
GET produkty/_search
{
"query": {
"bool": {
"filter": {
"match": {
"kategoria": "tablety"
}
}
}
}
}
Wyszukujemy wszystkie produkty z kategorii "tablety" bez producenta "Apple",
gdzie producent jest polem nested nie włączanym do dokumentu
Bool - must_not ( nested )
GET produkty/_search
{
"query": {
"bool": {
"must": {
"match": {
"kategoria": "tablety"
}
},
"must_not": {
"nested": {
"path": "producent",
"query": {
"match": {
"producent.name": "Apple"
}
}
}
}
}
}
}
Wyszukujemy wszystkie produkty z kategorii "tablety" bez producenta "Apple"
Bool - must_not
GET produkty_producent/_search
{
"query": {
"bool": {
"must": {
"match": {
"kategoria": "tablety"
}
},
"must_not": {
"match": {
"producent.name": "Apple"
}
}
}
}
}
Wyszukujemy wszystkie produkty od producenta "Apple" lub "Samsung"
Bool - should
GET produkty_producent/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"producent.name": "Apple"
}
},
{
"match": {
"producent.name": "Samsung"
}
}
]
}
}
}
POST _reindex?wait_for_completion=false
{
"source": {
"index": "movies_v1"
},
"dest": {
"index": "movies_v2"
}
}
Zakładamy index movies_v2 i dodajemy "index_prefixes": { } w polu title
{
"task" : "a9qwXzi2RG6HwYAmSwp6Hg:47188"
}
GET _tasks/a9qwXzi2RG6HwYAmSwp6Hg:47188
{
"completed" : true,
"task" : {
"node" : "a9qwXzi2RG6HwYAmSwp6Hg",
"id" : 47188,
"type" : "transport",
"action" : "indices:data/write/reindex",
"status" : {
"total" : 18221,
"updated" : 0,
"created" : 18221,
"deleted" : 0,
"batches" : 19,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0
},
GET movies_v1/_search
{
"_source": ["title"],
"aggs": {
"pogrypowane": {
"terms": {
"field": "type",
"size": 10
}
}
}
}
GET movies_v1/_search
{
"_source": ["title"],
"aggs": {
"pogrypowane": {
"terms": {
"field": "type",
"size": 10
},
"aggs": {
...
}
}
}
}
Marcin
Lewandowski