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 suImport klucza PGP
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpgInstalacja pakietu apt-transport-https
sudo apt-get install apt-transport-httpsDodanie 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.listAktualizacja listy pakietów i instalacja Elasticsearch
sudo apt-get update && sudo apt-get install elasticsearchInstalacja serwera
Sprawdzamy czy serwis wystartował
systemctl status elasticsearch.service Startujemy serwis
systemctl start elasticsearch.service Instalacja serwera
Instalacja Kibany
sudo apt-get install kibanaDodajemy serwis do autostartu
systemctl enable kibanaKibana
Startujemy serwis
systemctl start kibanaSprawdzamy czy mamy dostęp do Kibany pod adresem
localhost:5601Instalacja serwera
Docker
Instalacja Docker
apt-get install docker.ioInstalacja Docker Compose
apt-get install docker-composeWymagania:
Instalacja serwera
Wyszukujemy odpowiedni obraz na Docker Hub np.
Docker
Startujemy kontener
docker run -d -p 9201:9200 -p 5602:5601 nshou/elasticsearch-kibanaSprawdzamy czy mamy dostęp do Kibany pod adresem
localhost:5602Sprawdzamy czy kontener został uruchomiony
docker psInstalacja 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 upUruchomienie środowiska w tle
docker-compose up -dSprawdzenie uruchomionych kontenerów
docker psZatrzymanie środowiska
ctrl + cZatrzymanie środowiska
docker-compose down
PUT shopDodajemy 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 _statsOdpowiedź
{
"_shards": {
...
},
"_all": {
...
},
"indices": {
"shop": {
...
}
}
}
CURL
curl -XGET 'localhost:9200/_stats?pretty'Usuwanie indeksu
Kibana
DELETE shopOdpowiedź
{
"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/_mappingSprawdzamy 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/_mappingSprawdzamy 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/_mappingSprawdzamy czy zmienił się mapping
...
"promotion": {
"type": "float"
}Odpowiedź
PUT shop
{
"mappings": {
"properties": {
... mapping ...
}
}
}Definiujemy mapping
Usuwamy indeks
DELETE shopPUT 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/_closePOST /shop/_openZamykamy 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.txtImport 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.txtSprawdzamy 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