ElasticsearchのSearch APIを試す
ElasticsearchでSearch APIを使ってみたメモです。
前回ElasticsearchとKibanaをインストールしたので、Search APIを使ってみました。
公式のサンプルを試しただけなので、下記の公式ドキュメントを見たほうが早いです。
www.elastic.co
Consoleで使ってみます。
サンプルデータ登録
サンプルデータセットを下記からダウンロードします。
銀行の口座のダミーデータになってます。
https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json
データの登録ですが、curlだと下記のように--data-binaryでファイル名を指定すれば登録できますが、
Consoleからだと出来ないようです(たぶん)。
curl -XPOST 'localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json"
なので、データをコピーしてそのままConsoleに全部貼り付けて登録します。
bulk APIを使用して登録します。bulk APIを使用すると一度のリクエストで複数の登録/削除が出来ます。
bankインデックスのaccountタイプに登録。
POST /bank/account/_bulk?pretty&refresh { "index": { "_id": "1" } } { "account_number": 1, "balance": 39225, "firstname": "Amber", "lastname": "Duke", "age": 32, "gender": "M", "address": "880 Holmes Lane", "employer": "Pyrami", "email": "amberduke@pyrami.com", "city": "Brogan", "state": "IL" } { "index": { "_id": "6" } } { "account_number": 6, "balance": 5686, "firstname": "Hattie", "lastname": "Bond", "age": 36, "gender": "M", "address": "671 Bristol Street", "employer": "Netagy", "email": "hattiebond@netagy.com", "city": "Dante", "state": "TN" } : : :
レスポンス。
{ "took": 1291, "errors": false, "items": [ { "index": { "_index": "bank", "_type": "account", "_id": "1", "_version": 1, "result": "created", "forced_refresh": true, "_shards": { "total": 2, "successful": 1, "failed": 0 }, "created": true, "status": 201 } }, { "index": { "_index": "bank", "_type": "account", "_id": "6", "_version": 1, "result": "created", "forced_refresh": true, "_shards": { "total": 2, "successful": 1, "failed": 0 }, "created": true, "status": 201 } }, : : :
cat APIを使用して、index情報を確認。
GET _cat/indices?v
レスポンス。docs.countで1000件登録されたことがわかります。
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open bank CEbEH4CPTX-fANp3RtD0Bg 5 1 1000 0 648.9kb 648.9kb yellow open .kibana J4PlELzCRu-7_kI76iDCsQ 1 1 1 0 3.2kb 3.2kb
Search API
Search APIを実行する方法は2通りあって、REST request URIにパラメータを指定する方法と、
REST request BODYにjsonを指定する方法があります。
リクエストパラメータでbankインデックスを全件取得してみます。
Search APIは_searchがエンドポイントになってます。
各パラメータは下記の通り。
・q=*:全ドキュメントを対象
・sort=account_number:asc:account_numberの昇順でソート
・pretty:整形されたjsonのレスポンスを要求
GET /bank/_search?q=*&sort=account_number:asc&pretty
レスポンス。
・took:検索の処理時間(msec)
・timed_out:検索のタイムアウト有無。false⇒タイムアウトしてない
・_shards:検索されたシャードの数
・hits:検索結果
・hits.total:検索条件に一致する全ドキュメント数
・hits.hits:検索結果の配列(デフォルトは10ドキュメント)
・sort:ソートの順番
{ "took": 16, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": null, "hits": [ { "_index": "bank", "_type": "account", "_id": "0", "_score": null, "_source": { "account_number": 0, "balance": 16623, "firstname": "Bradshaw", "lastname": "Mckenzie", "age": 29, "gender": "F", "address": "244 Columbus Place", "employer": "Euron", "email": "bradshawmckenzie@euron.com", "city": "Hobucken", "state": "CO" }, "sort": [ 0 ] }, { "_index": "bank", "_type": "account", "_id": "1", "_score": null, "_source": { "account_number": 1, "balance": 39225, "firstname": "Amber", "lastname": "Duke", "age": 32, "gender": "M", "address": "880 Holmes Lane", "employer": "Pyrami", "email": "amberduke@pyrami.com", "city": "Brogan", "state": "IL" }, "sort": [ 1 ] }, : : : { "_index": "bank", "_type": "account", "_id": "9", "_score": null, "_source": { "account_number": 9, "balance": 24776, "firstname": "Opal", "lastname": "Meadows", "age": 39, "gender": "M", "address": "963 Neptune Avenue", "employer": "Cedward", "email": "opalmeadows@cedward.com", "city": "Olney", "state": "OH" }, "sort": [ 9 ] } ] } }
同じ検索をリクエストボディで実行してみます。
q=*の代わりに下記のjsonを指定します。
・"match_all":{}:すべてのドキュメントを対象。
・"sort":account_numberの昇順でソート
GET /bank/_search?pretty { "query": { "match_all": {} }, "sort": [ { "account_number": "asc" } ] }
レスポンス。
{ "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": null, "hits": [ { "_index": "bank", "_type": "account", "_id": "0", "_score": null, "_source": { "account_number": 0, "balance": 16623, "firstname": "Bradshaw", "lastname": "Mckenzie", "age": 29, "gender": "F", "address": "244 Columbus Place", "employer": "Euron", "email": "bradshawmckenzie@euron.com", "city": "Hobucken", "state": "CO" }, "sort": [ 0 ] }, { "_index": "bank", "_type": "account", "_id": "1", "_score": null, "_source": { "account_number": 1, "balance": 39225, "firstname": "Amber", "lastname": "Duke", "age": 32, "gender": "M", "address": "880 Holmes Lane", "employer": "Pyrami", "email": "amberduke@pyrami.com", "city": "Brogan", "state": "IL" }, "sort": [ 1 ] }, : : : { "_index": "bank", "_type": "account", "_id": "9", "_score": null, "_source": { "account_number": 9, "balance": 24776, "firstname": "Opal", "lastname": "Meadows", "age": 39, "gender": "M", "address": "963 Neptune Avenue", "employer": "Cedward", "email": "opalmeadows@cedward.com", "city": "Olney", "state": "OH" }, "sort": [ 9 ] } ] } }
match_all
match_allですべてのドキュメントを対象に検索します。
GET /bank/_search?pretty { "query": { "match_all": {} } }
レスポンス
{ "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "25", "_score": 1, "_source": { "account_number": 25, "balance": 40540, "firstname": "Virginia", "lastname": "Ayala", "age": 39, "gender": "F", "address": "171 Putnam Avenue", "employer": "Filodyne", "email": "virginiaayala@filodyne.com", "city": "Nicholson", "state": "PA" } }, { "_index": "bank", "_type": "account", "_id": "44", "_score": 1, "_source": { "account_number": 44, "balance": 34487, "firstname": "Aurelia", "lastname": "Harding", "age": 37, "gender": "M", "address": "502 Baycliff Terrace", "employer": "Orbalix", "email": "aureliaharding@orbalix.com", "city": "Yardville", "state": "DE" } }, : : :
size
sizeで結果のドキュメント数を指定。デフォルトは10です。
GET /bank/_search?pretty { "query": { "match_all": {} }, "size": 1 }
レスポンス。
{ "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "25", "_score": 1, "_source": { "account_number": 25, "balance": 40540, "firstname": "Virginia", "lastname": "Ayala", "age": 39, "gender": "F", "address": "171 Putnam Avenue", "employer": "Filodyne", "email": "virginiaayala@filodyne.com", "city": "Nicholson", "state": "PA" } } ] } }
from
fromで開始するドキュメントのインデックスを指定します。デフォルトは0。
sizeを指定すると、fromから始まりsize件のドキュメントを返します。
GET /bank/_search?pretty { "query": { "match_all": {} }, "from": 10, "size": 10 }
レスポンス。
{ "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "227", "_score": 1, "_source": { "account_number": 227, "balance": 19780, "firstname": "Coleman", "lastname": "Berg", "age": 22, "gender": "M", "address": "776 Little Street", "employer": "Exoteric", "email": "colemanberg@exoteric.com", "city": "Eagleville", "state": "WV" } }, { "_index": "bank", "_type": "account", "_id": "253", "_score": 1, "_source": { "account_number": 253, "balance": 20240, "firstname": "Melissa", "lastname": "Gould", "age": 31, "gender": "M", "address": "440 Fuller Place", "employer": "Buzzopia", "email": "melissagould@buzzopia.com", "city": "Lumberton", "state": "MD" } }, : : :
sort, order
sortでソートするフィールドを指定し、orderでソート順を指定します。
下記では、balanceフィールドの降順にソートします。
GET /bank/_search?pretty { "query": { "match_all": {} }, "sort": { "balance": { "order": "desc" } } }
レスポンス。
{ "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": null, "hits": [ { "_index": "bank", "_type": "account", "_id": "248", "_score": null, "_source": { "account_number": 248, "balance": 49989, "firstname": "West", "lastname": "England", "age": 36, "gender": "M", "address": "717 Hendrickson Place", "employer": "Obliq", "email": "westengland@obliq.com", "city": "Maury", "state": "WA" }, "sort": [ 49989 ] }, { "_index": "bank", "_type": "account", "_id": "854", "_score": null, "_source": { "account_number": 854, "balance": 49795, "firstname": "Jimenez", "lastname": "Barry", "age": 25, "gender": "F", "address": "603 Cooper Street", "employer": "Verton", "email": "jimenezbarry@verton.com", "city": "Moscow", "state": "AL" }, "sort": [ 49795 ] }, : : :
_source
検索結果はすべてのフィールドを返します。
一部のフィールドのみ返してほしい場合は_sourceフィールドを指定します。
SQLでいう、SELECT FROMで指定するカラムに似ています。
下記の場合、account_numberとbalanceフィールドのみ返すように指定しています。
GET /bank/_search?pretty { "query": { "match_all": {} }, "_source": ["account_number", "balance"] }
レスポンス。
{ "took": 22, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "25", "_score": 1, "_source": { "account_number": 25, "balance": 40540 } }, { "_index": "bank", "_type": "account", "_id": "44", "_score": 1, "_source": { "account_number": 44, "balance": 34487 } }, : : :
match
matchでフィールドの検索を指定することが出来ます。
下記の場合、account_numberが20のドキュメントを返します。
GET /bank/_search?pretty { "query": { "match": { "account_number": 20 } } }
レスポンス。
{ "took": 12, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "20", "_score": 1, "_source": { "account_number": 20, "balance": 16418, "firstname": "Elinor", "lastname": "Ratliff", "age": 36, "gender": "M", "address": "282 Kings Place", "employer": "Scentric", "email": "elinorratliff@scentric.com", "city": "Ribera", "state": "WA" } } ] } }
下記の場合、addressにmillを含むドキュメントを返します(部分一致)。
GET /bank/_search?pretty { "query": { "match": { "address": "mill" } } }
レスポンス。
{ "took": 8, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 4, "max_score": 4.3100996, "hits": [ { "_index": "bank", "_type": "account", "_id": "472", "_score": 4.3100996, "_source": { "account_number": 472, "balance": 25571, "firstname": "Lee", "lastname": "Long", "age": 32, "gender": "F", "address": "288 Mill Street", "employer": "Comverges", "email": "leelong@comverges.com", "city": "Movico", "state": "MT" } }, { "_index": "bank", "_type": "account", "_id": "136", "_score": 4.2662063, "_source": { "account_number": 136, "balance": 45801, "firstname": "Winnie", "lastname": "Holland", "age": 38, "gender": "M", "address": "198 Mill Lane", "employer": "Neteria", "email": "winnieholland@neteria.com", "city": "Urie", "state": "IL" } }, { "_index": "bank", "_type": "account", "_id": "970", "_score": 3.861861, "_source": { "account_number": 970, "balance": 19648, "firstname": "Forbes", "lastname": "Wallace", "age": 28, "gender": "M", "address": "990 Mill Road", "employer": "Pheast", "email": "forbeswallace@pheast.com", "city": "Lopezo", "state": "AK" } }, { "_index": "bank", "_type": "account", "_id": "345", "_score": 3.861861, "_source": { "account_number": 345, "balance": 9812, "firstname": "Parker", "lastname": "Hines", "age": 38, "gender": "M", "address": "715 Mill Avenue", "employer": "Baluba", "email": "parkerhines@baluba.com", "city": "Blackgum", "state": "KY" } } ] } }
下記の例ではaddressにmillまたはlaneを含むドキュメントを返します。
GET /bank/_search?pretty { "query": { "match": { "address": "mill lane" } } }
レスポンス
{ "took": 15, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 19, "max_score": 7.3900023, "hits": [ { "_index": "bank", "_type": "account", "_id": "136", "_score": 7.3900023, "_source": { "account_number": 136, "balance": 45801, "firstname": "Winnie", "lastname": "Holland", "age": 38, "gender": "M", "address": "198 Mill Lane", "employer": "Neteria", "email": "winnieholland@neteria.com", "city": "Urie", "state": "IL" } }, { "_index": "bank", "_type": "account", "_id": "472", "_score": 4.3100996, "_source": { "account_number": 472, "balance": 25571, "firstname": "Lee", "lastname": "Long", "age": 32, "gender": "F", "address": "288 Mill Street", "employer": "Comverges", "email": "leelong@comverges.com", "city": "Movico", "state": "MT" } }, { "_index": "bank", "_type": "account", "_id": "556", "_score": 3.9074605, "_source": { "account_number": 556, "balance": 36420, "firstname": "Collier", "lastname": "Odonnell", "age": 35, "gender": "M", "address": "591 Nolans Lane", "employer": "Sultraxin", "email": "collierodonnell@sultraxin.com", "city": "Fulford", "state": "MD" } }, : : :
match_phrase
match_phraseを使用すると、addressにmillとlane両方含むドキュメントを検索できます。
GET /bank/_search?pretty { "query": { "match_phrase": { "address": "mill lane" } } }
レスポンス
{ "took": 12, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 7.3900023, "hits": [ { "_index": "bank", "_type": "account", "_id": "136", "_score": 7.3900023, "_source": { "account_number": 136, "balance": 45801, "firstname": "Winnie", "lastname": "Holland", "age": 38, "gender": "M", "address": "198 Mill Lane", "employer": "Neteria", "email": "winnieholland@neteria.com", "city": "Urie", "state": "IL" } } ] } }
bool query
bool queryを使用すると、各bool句の結果のbool値を組み合わせてクエリを実行できます。
must
下記の例では2つのmatchクエリを作成し、must句でどちらの結果もtrueとなるドキュメントを検索します。
結果としてaddressにmillとlane両方含むドキュメントが返ります。
GET /bank/_search?pretty { "query": { "bool": { "must": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
レスポンス
{ "took": 8, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 7.3900023, "hits": [ { "_index": "bank", "_type": "account", "_id": "136", "_score": 7.3900023, "_source": { "account_number": 136, "balance": 45801, "firstname": "Winnie", "lastname": "Holland", "age": 38, "gender": "M", "address": "198 Mill Lane", "employer": "Neteria", "email": "winnieholland@neteria.com", "city": "Urie", "state": "IL" } } ] } }
should
下記の例では2つのmatchクエリを作成し、should句でいずれかの結果がtrueとなるドキュメントを検索します。
(一致するshould句の最小数はminimum_should_matchで指定可能)
結果としてaddressにmillまたはlaneを含むドキュメントが返ります。
GET /bank/_search?pretty { "query": { "bool": { "should": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
レスポンス
{ "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 19, "max_score": 7.3900023, "hits": [ { "_index": "bank", "_type": "account", "_id": "136", "_score": 7.3900023, "_source": { "account_number": 136, "balance": 45801, "firstname": "Winnie", "lastname": "Holland", "age": 38, "gender": "M", "address": "198 Mill Lane", "employer": "Neteria", "email": "winnieholland@neteria.com", "city": "Urie", "state": "IL" } }, { "_index": "bank", "_type": "account", "_id": "472", "_score": 4.3100996, "_source": { "account_number": 472, "balance": 25571, "firstname": "Lee", "lastname": "Long", "age": 32, "gender": "F", "address": "288 Mill Street", "employer": "Comverges", "email": "leelong@comverges.com", "city": "Movico", "state": "MT" } }, { "_index": "bank", "_type": "account", "_id": "556", "_score": 3.9074605, "_source": { "account_number": 556, "balance": 36420, "firstname": "Collier", "lastname": "Odonnell", "age": 35, "gender": "M", "address": "591 Nolans Lane", "employer": "Sultraxin", "email": "collierodonnell@sultraxin.com", "city": "Fulford", "state": "MD" } }, : : :
must_not
下記の例では2つのmatchクエリを作成し、must_not句で結果がtrueとなるドキュメントを除外します。
結果としてaddressにmillとlaneのいずれも含まないドキュメントが返ります。
GET /bank/_search?pretty { "query": { "bool": { "must_not": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }
レスポンス
{ "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 981, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "25", "_score": 1, "_source": { "account_number": 25, "balance": 40540, "firstname": "Virginia", "lastname": "Ayala", "age": 39, "gender": "F", "address": "171 Putnam Avenue", "employer": "Filodyne", "email": "virginiaayala@filodyne.com", "city": "Nicholson", "state": "PA" } }, { "_index": "bank", "_type": "account", "_id": "44", "_score": 1, "_source": { "account_number": 44, "balance": 34487, "firstname": "Aurelia", "lastname": "Harding", "age": 37, "gender": "M", "address": "502 Baycliff Terrace", "employer": "Orbalix", "email": "aureliaharding@orbalix.com", "city": "Yardville", "state": "DE" } }, : : :
bool queryではmust、should、must_notはそれぞれ組み合わせることが出来ます。
下記の例では、年齢が40歳でID(アイダホ州)でないドキュメントが返ります。
GET /bank/_search?pretty { "query": { "bool": { "must": [ { "match": { "age": "40" } } ], "must_not": [ { "match": { "state": "ID" } } ] } } }
レスポンス
{ "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 43, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "948", "_score": 1, "_source": { "account_number": 948, "balance": 37074, "firstname": "Sargent", "lastname": "Powers", "age": 40, "gender": "M", "address": "532 Fiske Place", "employer": "Accuprint", "email": "sargentpowers@accuprint.com", "city": "Umapine", "state": "AK" } }, { "_index": "bank", "_type": "account", "_id": "40", "_score": 1, "_source": { "account_number": 40, "balance": 33882, "firstname": "Pace", "lastname": "Molina", "age": 40, "gender": "M", "address": "263 Ovington Court", "employer": "Cytrak", "email": "pacemolina@cytrak.com", "city": "Silkworth", "state": "OR" } }, : : :
range
filter句でフィルタリングを指定でき、range句で範囲を指定できます。
下記の例では残高が20000〜30000の口座を検索します。
GET /bank/_search?pretty { "query": { "bool": { "must": { "match_all": {} }, "filter": { "range": { "balance": { "gte": 20000, "lte": 30000 } } } } } }
レスポンス
{ "took": 34, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 217, "max_score": 1, "hits": [ { "_index": "bank", "_type": "account", "_id": "253", "_score": 1, "_source": { "account_number": 253, "balance": 20240, "firstname": "Melissa", "lastname": "Gould", "age": 31, "gender": "M", "address": "440 Fuller Place", "employer": "Buzzopia", "email": "melissagould@buzzopia.com", "city": "Lumberton", "state": "MD" } }, { "_index": "bank", "_type": "account", "_id": "400", "_score": 1, "_source": { "account_number": 400, "balance": 20685, "firstname": "Kane", "lastname": "King", "age": 21, "gender": "F", "address": "405 Cornelia Street", "employer": "Tri@Tribalog", "email": "kaneking@tri@tribalog.com", "city": "Gulf", "state": "VT" } }, : : :
aggs
aggregations(aggs)を使用して、結果に対して様々な集計が出来ます。
group_by_stateという集計の名前を定義します。
termsで指定されたいずれかの値を含む文書を検索します。
下記の例ではstateでグループ化して、件数の降順でソートします。
GET /bank/_search?pretty { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" } } } }
レスポンス
{ "took": 49, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 0, "hits": [] }, "aggregations": { "group_by_state": { "doc_count_error_upper_bound": 20, "sum_other_doc_count": 770, "buckets": [ { "key": "ID", "doc_count": 27 }, { "key": "TX", "doc_count": 27 }, { "key": "AL", "doc_count": 25 }, { "key": "MD", "doc_count": 25 }, { "key": "TN", "doc_count": 23 }, { "key": "MA", "doc_count": 21 }, : : :
SQLだと下記をシミュレートした感じです。
SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
さらに集計した結果からstate別の平均残高で集計する場合の例。
aggsはネストすることができます。
GET /bank/_search?pretty { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } }
レスポンス
{ "took": 23, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 0, "hits": [] }, "aggregations": { "group_by_state": { "doc_count_error_upper_bound": 20, "sum_other_doc_count": 770, "buckets": [ { "key": "ID", "doc_count": 27, "average_balance": { "value": 24368.777777777777 } }, { "key": "TX", "doc_count": 27, "average_balance": { "value": 27462.925925925927 } }, { "key": "AL", "doc_count": 25, "average_balance": { "value": 25739.56 } }, { "key": "MD", "doc_count": 25, "average_balance": { "value": 24963.52 } }, : : :
先程の例を平均残高の降順でソートする場合。
GET /bank/_search?pretty { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword", "order": { "average_balance": "desc" } }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } }
レスポンス
{ "took": 7, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 0, "hits": [] }, "aggregations": { "group_by_state": { "doc_count_error_upper_bound": -1, "sum_other_doc_count": 918, "buckets": [ { "key": "AL", "doc_count": 6, "average_balance": { "value": 41418.166666666664 } }, { "key": "SC", "doc_count": 1, "average_balance": { "value": 40019 } }, { "key": "AZ", "doc_count": 10, "average_balance": { "value": 36847.4 } }, { "key": "VA", "doc_count": 13, "average_balance": { "value": 35418.846153846156 } }, : : :
さらに、年齢層別(20歳~29歳、30歳~39歳、40歳~49歳)にグループ化してから性別でグループ化し、
年齢層別の性別ごとの平均残高を取得する場合。
GET /bank/_search?pretty { "size": 0, "aggs": { "group_by_age": { "range": { "field": "age", "ranges": [ { "from": 20, "to": 30 }, { "from": 30, "to": 40 }, { "from": 40, "to": 50 } ] }, "aggs": { "group_by_gender": { "terms": { "field": "gender.keyword" }, "aggs": { "average_balance": { "avg": { "field": "balance" } } } } } } } }
レスポンス
{ "took": 36, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1000, "max_score": 0, "hits": [] }, "aggregations": { "group_by_age": { "buckets": [ { "key": "20.0-30.0", "from": 20, "to": 30, "doc_count": 451, "group_by_gender": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "M", "doc_count": 232, "average_balance": { "value": 27374.05172413793 } }, { "key": "F", "doc_count": 219, "average_balance": { "value": 25341.260273972603 } } ] } }, { "key": "30.0-40.0", "from": 30, "to": 40, "doc_count": 504, "group_by_gender": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "F", "doc_count": 253, "average_balance": { "value": 25670.869565217392 } }, { "key": "M", "doc_count": 251, "average_balance": { "value": 24288.239043824702 } } ] } }, { "key": "40.0-50.0", "from": 40, "to": 50, "doc_count": 45, "group_by_gender": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "M", "doc_count": 24, "average_balance": { "value": 26474.958333333332 } }, { "key": "F", "doc_count": 21, "average_balance": { "value": 27992.571428571428 } } ] } } ] } } }
公式のドキュメントが順序を追って学べる形になっていたので分かりやすかったです。
終わり。