このブログの目的
本ブログシリーズの目的は、Elastic Certified Engineer Examの合格に必要な知識と実装スキルを体系的に習得することです。本記事では、Elastic社が公開している試験ガイドの以下の試験範囲に関連する内容を扱います。
Searching Data – Write an asynchronous search
Searching Data – Write and execute a query that searches across multiple clusters
Async Searchは、検索処理を非同期で実行し、検索IDを利用して後から結果を取得できる機能です。一方、Cross Cluster Search(CCS)は、Remote Cluster上のIndexをローカルクラスタから検索できる機能です。どちらも通常のSearch APIを応用した実践的な機能であり、試験では要件に応じて適切なAPIや検索構文を実装できることが求められます。
本記事では、Async Search APIの実装方法や主要オプション、Cross Cluster Searchの検索構文に加え、両者を組み合わせた実践的なクエリの実装方法について解説します。試験で求められるポイントを押さえながら、実際にDev Toolsでクエリを実装できるレベルを目指しましょう。
試験情報は以下サイトで確認可能です。
https://www.elastic.co/training/elastic-certified-engineer-examAsynchronous Search(非同期検索)
Asynchronous Searchとは
Asynchronous Search(非同期検索)は、検索処理の完了を待たずに検索を開始し、検索IDを受け取った後に結果を取得できる検索機能です。通常の検索(同期検索)は検索処理が完了するまでレスポンスが返されませんが、Asynchronous Searchでは検索開始直後に検索IDが返されるため、長時間かかる検索でもクライアントが待機し続ける必要がありません。
通常検索との違い
通常の検索では、検索処理が完了してから検索結果が返されます。一方、Asynchronous Searchでは検索開始時に検索IDが返され、検索が完了していなくても進捗状況や途中結果を取得できます。検索結果は一定期間保持されるため、後から同じ検索IDを指定して結果を取得することも可能です。
なぜ必要か
大量のDocumentを対象とした検索や、多数のAggregationを含む検索では、処理に時間がかかることがあります。このような検索を同期的に実行すると、クライアント側でタイムアウトが発生したり、接続を維持し続ける必要があります。Asynchronous Searchを利用することで、検索をバックグラウンドで実行しながら、必要なタイミングで結果を取得できるため、長時間実行される検索でも効率的に処理できます。
利用シーン
Asynchronous Searchは、大規模なログ分析や長期間の時系列データ検索、多数のBucket AggregationやPipeline Aggregationを組み合わせた集計処理など、実行時間が長くなる検索で利用されます。また、Webアプリケーションやダッシュボードにおいて、検索完了を待たずに画面を操作しながら結果を取得したい場合にも有効です。
Elastic API Docs > Search > Run an async search
https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-async-search-submit
Async Searchに関する詳細な情報は、Elastic DocsよりもElastic API Docsにまとまっています。API仕様に加え、リクエスト・レスポンスのサンプルや各パラメータの説明も掲載されているため、試験中に実装方法が分からなくなった場合は、Elastic API Docsを参照することをお勧めします。
Async Search API
Async Search APIでは、検索を非同期で実行し、検索IDを使って後から検索結果を取得できます。通常のSearch APIでは検索完了までレスポンスを待ちますが、Async Search APIでは検索処理を開始した後、検索IDを受け取り、そのIDを指定して結果や進行状況を確認します。
主に次の3つの操作を理解しておくことが重要です。
| 操作 | API | 目的 |
|---|---|---|
| 検索の開始 | POST /{index}/_async_search | 非同期検索を開始する |
| 結果の取得 | GET /_async_search/{id} | 検索IDを指定して結果を取得する |
| 検索結果の削除 | DELETE /_async_search/{id} | 保持されている検索結果を削除する |
非同期検索を開始する
POST /{index}/_async_search次の例では、kibana_sample_data_logs を対象に、日付ごとのアクセス数と転送バイト数を集計します。
POST /kibana_sample_data_logs/_async_search?wait_for_completion_timeout=1s&keep_alive=5m
{
"size": 0,
"query": {
"range": {
"@timestamp": {
"gte": "now-30d/d",
"lt": "now/d"
}
}
},
"aggs": {
"access_per_day": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "day"
},
"aggs": {
"total_bytes": {
"sum": {
"field": "bytes"
}
}
}
}
}
}| タイトル | クエリのポイント | 解説 |
|---|---|---|
| API | POST /kibana_sample_data_logs/_async_search | kibana_sample_data_logsに対してAsync Searchを実行します。通常の_searchではなく_async_searchを使用することで、検索処理を非同期で実行できます。 |
| 待機時間 | wait_for_completion_timeout=1s | 検索開始後、最大1秒だけ検索完了を待ちます。1秒以内に完了しない場合は、検索IDが返され、後から結果を取得できます。 |
| 保持期間 | keep_alive=5m | 非同期検索の結果を5分間保持します。この期間内であれば、返された検索IDを使って結果を再取得できます。 |
| 取得件数 | “size”: 0 | 検索結果のDocumentは返さず、Aggregation結果のみを取得します。集計のみを行う場合によく利用されます。 |
| 検索条件 | range Query | @timestampを条件に、検索対象期間を絞り込んでいます。 |
| 開始日時 | “gte”: “now-30d/d” | 現在日時を基準に、30日前の0時以降を検索対象とします。 |
| 終了日時 | “lt”: “now/d” | 今日の0時より前までを検索対象とします。つまり、昨日までの30日間を検索します。 |
| 親Aggregation | access_per_day | 日単位で集計するための親Aggregationです。任意の名前ですが、集計内容が分かる名称を付けています。 |
| Bucket作成 | date_histogram | @timestampを基準に日単位のBucketを作成します。時系列データの集計でよく利用されます。 |
| 集計単位 | calendar_interval: “day” | カレンダー上の1日単位でBucketを作成します。 |
| 子Aggregation | total_bytes | 各Bucket内で実行されるSub Aggregationです。 |
| 集計方法 | sum Aggregation | 各Bucket内のbytesフィールドの合計値を計算します。 |
| 集計対象 | field: “bytes” | 合計値を算出する対象フィールドです。ログの転送バイト数を集計しています。 |
このクエリでは、date_histogramで日付ごとのBucketを作成し、その配下でsum Aggregationを使ってbytesの合計値を算出しています。検索やAggregationの処理に時間がかかる場合でも、Async Searchを利用することで検索処理を開始し、後から結果を確認できます。
実行結果の確認

筆者のローカル環境で上記のサンプルコマンドを実行したところ、検索はwait_for_completion_timeoutの時間内に完了したため、レスポンスには検索結果が含まれていました。
次に、検索完了を待たずにレスポンスを返すようクエリを変更し、Async Searchの動作を確認してみます。以下のように”wait_for_completion_timeout”に”0ms”を指定します。
POST /kibana_sample_data_logs/_async_search?wait_for_completion_timeout=0ms&keep_alive=5m
{
"size": 0,
"query": {
"range": {
"@timestamp": {
"gte": "now-30d/d",
"lt": "now/d"
}
}
},
"aggs": {
"access_per_day": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "day"
},
"aggs": {
"total_bytes": {
"sum": {
"field": "bytes"
}
}
}
}
}
}
実行結果

検索完了を待たない指定でクエリを実行した為、
・id : FkYzcGR6RThMUS1LTFRPTE1QdEoxVEEeWnQ1WUFtNjNRUXFEdXBGTExqcG5aZzoxOTk4Njcz
・is_partial : true
・is_running : true
が返却されました。idは、後続の結果取得や削除で使用します。is_runningがtrueの場合は検索処理が継続中であり、is_partialがtrueの場合は結果がまだ完全ではないことを示します。
次に、返却されたIDを指定してクエリを実行します。なお、以下のIDは筆者の実行環境で返却された値です。実際に実行する場合は、ご自身の環境で返却されたIDに置き換えてください。
get _async_search/FkYzcGR6RThMUS1LTFRPTE1QdEoxVEEeWnQ1WUFtNjNRUXFEdXBGTExqcG5aZzoxOTk4Njcz
IDを指定し_async_searchを実行することで、検索結果を取得できています。
検索結果を削除する
保持されている非同期検索の結果が不要になった場合は、検索IDを指定して削除します。
keep_aliveで指定した期間が経過すると検索結果は自動的に削除されますが、不要になった検索結果は明示的に削除できます。
DELETE /_async_search/FkYzcGR6RThMUS1LTFRPTE1QdEoxVEEeWnQ1WUFtNjNRUXFEdXBGTExqcG5aZzoxOTk4Njcz
上図の通り、delete文でidを指定し、保持されている検索結果を削除することができました。
主なオプション
| オプション | 説明 |
|---|---|
| wait_for_completion_timeout | 指定した時間だけ検索完了を待つ。時間内に完了しない場合は検索IDを返す |
| keep_alive | 非同期検索の結果を保持する期間を指定する |
| keep_on_completion | keep_on_completionをtrueにすると、指定時間内に検索が完了した場合でも、結果を保存する |
試験対策
Elastic Certified Engineer Examでは、次の流れをDev Toolsで実行できることが重要です。
1. POST /{index}/_async_search で検索を開始する
2. レスポンスの id を確認する
3. GET /_async_search/{id} で結果を取得する
4. DELETE /_async_search/{id} で不要な検索結果を削除する
特に、通常のSearch APIとの違いとして「検索IDを受け取り、後から結果を取得する」という点を理解しておく必要があります。
・wait_for_completion_timeout
・keep_alive
・keep_on_completion
の役割を押さえておくと、試験で要件に応じたAsync Searchを実装しやすくなります。
期間指定の補足
期間指定の補足
クエリでは、検索対象期間を「過去30日間(今日を除く)」に限定しています。
now:クエリ実行時点の日時を表します。30d:30日前を表します。/d:日時を「日単位」で切り捨て、当日の0時00分00秒に丸めます(Day Rounding)。gte(Greater Than or Equal):指定日時以上を検索対象にします。lt(Less Than):指定日時より前を検索対象にします。例えば、2026年6月26日 10:57 にクエリを実行した場合、それぞれ次の日時に変換されます。
指定値 変換後の日時 now-30d/d 2026年5月27日 00:00:00 now/d 2026年6月26日 00:00:00 そのため、実際の検索対象期間は次のようになります。
2026/05/27 00:00:00 ≦ @timestamp < 2026/06/26 00:00:00つまり、2026年5月27日から2026年6月25日までの30日間が検索対象となり、6月26日(今日)のデータは含まれません。
“/d”を付けない場合との違い
もし次のように
/dを指定しなかった場合、"gte": "now-30d", "lt": "now"2026年6月26日 10:57に実行すると、検索対象期間は次のようになります。
2026/05/27 10:57:00 ≦ @timestamp < 2026/06/26 10:57:00この場合、開始・終了時刻が実行時刻に依存するため、日単位の集計では意図しない結果になることがあります。
ログ分析や時系列データの集計では、
/dを指定して日付の境界(0時)に揃えることで、「昨日までの30日間」や「今日以降」など、日単位で分かりやすく期間を指定できます。
補足:_async_searchでは、Sort・Pagingも利用可能
Async Searchは通常のSearch APIを非同期で実行するAPIであるため、queryやaggregationsだけでなく、sort、from、size、search_afterなども通常のSearch APIと同様に利用できます。なお、これらは検索開始時(POST /_async_search)に指定するものであり、検索IDを使って結果を取得するGET /_async_search/{id}では変更できません。
POST /kibana_sample_data_logs/_async_search { "query": { "match_all": {} }, "sort": [ { "@timestamp": { "order": "desc" } } ], "from": 0, "size": 10 }
Cross Cluster Search (CCS)
Cross Cluster Searchとは
Cross Cluster Search(CCS)は、リモートクラスタに保存されているIndexを、ローカルクラスタから検索できる機能です。検索対象のデータをあらかじめ複製する必要はなく、複数のクラスタに分散して保存されているデータを、1つの検索クエリで横断的に検索できます。
通常の検索との違い
通常の検索では、検索対象となるIndexは同一クラスタ内に存在している必要があります。一方、Cross Cluster Searchでは、検索対象となるクラスタを事前にRemote Clusterとして登録することで、別クラスタに存在するIndexも検索対象に含めることができます。
なぜ必要か
システムの規模が大きくなると、データ量や用途に応じて複数のElasticsearchクラスタを運用するケースがあります。例えば、本番環境と分析環境を分離したり、地域ごとにクラスタを分けて運用したりすることがあります。Cross Cluster Searchを利用することで、データを集約することなく、複数クラスタにまたがる検索を実現できます。
利用シーン
Cross Cluster Searchは、複数拠点で収集したログを一括で検索したい場合や、本番クラスタと分析クラスタを横断して検索したい場合などに利用されます。また、複数のElasticsearchクラスタを運用している環境において、単一の検索クエリで必要なデータを取得したい場合にも有効です。
試験対策
Elastic Certified Engineer Examでは、Remote Clusterを検索対象として指定するCCSクエリを実装できることが重要です。特に、
<cluster名>:<index名>
の形式で検索対象を指定し、複数クラスタを横断して検索する構文を理解しておきましょう。
試験では、通常cluster1とcluster2の2つのクラスタが用意されています。問題によっては、cluster2があらかじめcluster1のRemote Clusterとして登録されている場合があります。その場合は、設問で指定されたRemote Cluster名をそのまま利用してCCSクエリを作成すれば十分です。
一方、Remote Clusterが登録されていない状態で出題された場合は、まずRemote Clusterを登録した上でCCSクエリを実装することになります。Remote ClusterはPUT /_cluster/settings APIから登録できるほか、KibanaのManagement画面からも簡単に設定できます。
また、Remote ClusterはCross Cluster Search(CCS)だけでなく、Cross Cluster Replication(CCR)でも利用される重要な機能です。そのため、Remote Clusterの登録方法はCCSだけでなくCCRの試験対策としても習得が必須となります。API・Kibanaのどちらの方法でも設定できるよう、一度は実際に操作しておくことをお勧めします。
Cross Cluster Search API
最も基本的な検索構文は以下です。
GET /cluster2:kibana_sample_data_logs/_searchこの例では、cluster2というRemote Clusterに存在するkibana_sample_data_logsを検索しています。”cluster2” は、Remote Clusterの登録時に指定した名前です。CCSでは、この名前を検索対象として指定します。
複数のRemote Clusterを同時に検索する : カンマ区切り
複数のクラスタを横断して検索する場合は、検索対象をカンマ区切りで指定します。
GET cluster1:kibana_sample_data_logs,cluster2:kibana_sample_data_logs/_search
{
"query": {
"match_all": {}
}
}このクエリでは、cluster1とcluster2に存在するkibana_sample_data_logsを同時に検索します。
Wildcardを利用した検索
Remote Cluster名やIndex名にはWildcardも利用できます。
GET cluster*:kibana_sample_data_logs/_searchRemote Cluster名がcluster1、cluster2、cluster3のように命名されている場合、cluster*を指定することで一致するすべてのRemote Clusterを検索対象にできます。
また、Index名にもWildcardを利用できます。
GET /cluster2:kibana_sample_data*/_searchこの例では、cluster2上のkibana_sample_dataで始まるすべてのIndexを検索対象としています。
通常のSearch APIと同様の機能を利用可能
CCSでは、通常のSearch APIと同様にQuery DSLやAggregationを利用できます。
GET cluster2:kibana_sample_data_logs/_search
{
"query": {
"range": {
"@timestamp": {
"gte": "now-7d"
}
}
},
"aggs": {
"response_code": {
"terms": {
"field": "response.keyword"
}
}
}
}検索条件やAggregationの書き方は通常のSearch APIと変わらず、検索対象としてRemote Clusterを指定する点のみが異なります。
Elastic Docs > Explore and analyze > Cross-cluster search
https://www.elastic.co/docs/explore-analyze/cross-cluster-searchLocal環境でCCSを動作させるには、Remote Cluster環境を用意する必要があります。Remote Cluster環境を用意する場合、『LocalでRemote Clusterを登録する』を参照してください。
実践問題
Practical Exercise 1 – Async Search
You need to analyze recent access logs stored in the kibana_sample_data_logs index.
Write a query that satisfies the following requirements:
- Execute the search using the Async Search API.
- Wait up to 1 second for the search to complete.
- Keep the search result available for 5 minutes.
- Do not return any documents.
- Aggregate the number of log entries per day for the last 30 days.
Answer
POST /kibana_sample_data_logs/_async_search?wait_for_completion_timeout=1s&keep_alive=5m
{
"size": 0,
"query": {
"range": {
"@timestamp": {
"gte": "now-30d/d",
"lt": "now/d"
}
}
},
"aggs": {
"access_per_day": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "day"
}
}
}
}解説
この問題では、通常のSearch APIではなくAsync Search APIを利用して検索を実行します。検索完了まで最大1秒だけ待機し、それ以上時間がかかる場合は検索IDを受け取って後から結果を取得できるようにします。また、検索結果を5分間保持し、直近30日間(今日を除く)のアクセス数を日単位で集計することが求められます。
- Async Search API 通常の
_searchではなく_async_searchを使用し、検索を非同期で実行します。 - wait_for_completion_timeout
1sを指定し、検索完了を最大1秒だけ待機します。時間内に完了しない場合は検索IDが返されます。 - keep_alive
5mを指定し、検索結果を5分間保持します。保持期間中は検索IDを使って結果を再取得できます。 - 取得件数
"size": 0を指定し、Documentは返さずAggregation結果のみを取得します。 - 検索条件
rangeクエリで@timestampを対象に、過去30日間(今日を除く)のデータへ検索範囲を限定しています。 - Bucket Aggregation
date_histogramAggregationを使用し、calendar_interval: "day"によって日単位のBucketを作成します。 - 集計結果 各Bucketの
doc_countがその日のログ件数となるため、追加のMetric Aggregationは不要です。
Practical Exercise 2 – Cross Cluster Search
A remote cluster named cluster2 has already been configured.
Write a query that satisfies the following requirements:
- Search the
kibana_sample_data_ecommerceindex on the remote cluster. - Return only documents whose
categorycontains Women’s Clothing. - Sort the results by
taxful_total_pricein descending order. - Return the top 10 documents.
Answer
GET /cluster2:kibana_sample_data_ecommerce/_search
{
"query": {
"match": {
"category": "Women's Clothing"
}
},
"sort": [
{
"taxful_total_price": {
"order": "desc"
}
}
],
"size": 10
}解説
この問題では、Remote Clusterとして登録済みのcluster2に対してCross Cluster Search(CCS)を実行します。検索対象となるIndexはリモートクラスタ上のkibana_sample_data_ecommerceであり、categoryに「Women’s Clothing」を含むDocumentのみを検索します。また、taxful_total_priceの降順で並べ替え、上位10件のみを取得することが求められます。試験では、CCS特有の検索対象の指定方法と、通常のSearch APIと同じQuery DSLを組み合わせて実装できることが重要です。
- 検索対象
cluster2:kibana_sample_data_ecommerceを指定し、Remote Cluster上のIndexを検索します。 - Cross Cluster Search
<cluster名>:<index名>の形式で検索対象を指定します。通常のSearch APIとの違いは、この指定方法のみです。 - 検索条件
matchクエリを使用し、categoryにWomen's Clothingを含むDocumentを検索します。 - 並び替え
sortでtaxful_total_priceを指定し、order: "desc"によって価格の高い順に並び替えます。 - 取得件数
"size": 10を指定し、検索結果を上位10件に限定します。 - Query DSL
query、sort、sizeなどの指定方法は通常のSearch APIと同じであり、CCSでは検索対象の指定方法のみが異なります。
Practical Exercise 3 – Async Search + Cross Cluster Search
A remote cluster named cluster2 has already been configured.
Write a query that satisfies the following requirements:
- Search the
kibana_sample_data_ecommerceindex on the remote cluster. - Execute the search using the Async Search API.
- Wait up to 1 second for the search to complete.
- Keep the search result available for 5 minutes.
- Return only the following fields in
_source:order_idcustomer_full_nametaxful_total_pricetotal_quantitycategory
- Create a runtime field named
total_price_with_shipping. - The
total_price_with_shippingfield should calculatetaxful_total_price + 10. - Return the runtime field in the search response.
- Return only documents whose
taxful_total_priceis greater than or equal to100. - Sort the results by
taxful_total_pricein descending order. - Return the top 10 documents.
Answer
POST /cluster2:kibana_sample_data_ecommerce/_async_search?wait_for_completion_timeout=1s&keep_alive=5m
{
"_source": [
"order_id",
"customer_full_name",
"taxful_total_price",
"total_quantity",
"category"
],
"runtime_mappings": {
"total_price_with_shipping": {
"type": "double",
"script": {
"source": """
if (doc['taxful_total_price'].size() != 0) {
emit(doc['taxful_total_price'].value + 10);
}
"""
}
}
},
"fields": [
"total_price_with_shipping"
],
"query": {
"range": {
"taxful_total_price": {
"gte": 100
}
}
},
"sort": [
{
"taxful_total_price": {
"order": "desc"
}
}
],
"size": 10
}解説
この問題では、Async SearchとCross Cluster Search(CCS)を組み合わせて検索を実行します。検索対象はRemote Cluster上のkibana_sample_data_ecommerceであり、検索結果を非同期で取得しながら、Runtime Fieldを動的に生成してレスポンスへ含めます。また、取得するFieldを限定し、価格条件による絞り込み、並び替え、件数制限も実装する必要があります。試験では、複数の機能を組み合わせて要件どおりのクエリを実装できることが重要です。
- 検索対象
cluster2:kibana_sample_data_ecommerceを指定し、Remote Cluster上のIndexを検索します。 - Async Search API 通常の
_searchではなく_async_searchを使用し、検索を非同期で実行します。 - wait_for_completion_timeout
1sを指定し、検索完了を最大1秒だけ待機します。時間内に完了しない場合は検索IDが返されます。 - keep_alive
5mを指定し、検索結果を5分間保持します。保持期間中は検索IDを使って結果を再取得できます。 - 取得Field
_sourceで必要なFieldのみを指定し、不要なFieldを返さないようにしています。 - Runtime Field
runtime_mappingsでtotal_price_with_shippingを定義し、taxful_total_price + 10を動的に計算しています。 - Runtime Fieldの取得
fieldsにRuntime Field名を指定し、計算結果をレスポンスへ含めています。 - 検索条件
rangeクエリを使用し、taxful_total_priceが100以上のDocumentに絞り込んでいます。 - 並び替え
sortでtaxful_total_priceを指定し、order: "desc"によって価格の高い順に並び替えます。 - 取得件数
"size": 10を指定し、検索結果を上位10件に限定しています。 - 複合問題 Async Search、Cross Cluster Search、Runtime Field、Query DSLを組み合わせた問題であり、それぞれの機能を組み合わせて実装できることが試験では重要です。
Elastic社が提供する無料Hands-on Trainingで理解を深めよう
本記事では、Asynchronous SearchやCross Cluster Search(CCS)の基本的な仕組みや実装方法について解説しました。しかし、Elastic Certified Engineer Examでは、APIや構文を理解しているだけでは十分ではなく、要件に応じて適切な検索クエリを実装できることが求められます。
そのため、本記事で紹介したサンプルクエリは、実際にDev Toolsで繰り返し実行することをお勧めします。検索条件やオプションを変更しながら動作の違いを確認することで、Async Searchの実行フローやCross Cluster Searchの検索対象指定などを実践的に理解できます。
さらに、Elastic社が提供する無料のHands-on TrainingやOn-Demand Trainingでは、Elasticsearchを実際に操作しながら体系的に学習できます。Search APIやAggregationだけでなく、Ingest Pipeline、ILM、Data Stream、Cross Cluster Replication(CCR)など、試験範囲全体を実践形式で学習できるため、試験対策としても非常に有効です。
本記事で学習した内容とHands-on Trainingを組み合わせながら繰り返し実装を行い、試験本番でも要件に応じて迷わずAsync SearchやCross Cluster Searchを実装できるレベルを目指しましょう。
Elastic Cloud アカウント作成
https://cloud.elastic.co/registrationElastic Training
https://www.elastic.co/training
Elastic Learning Portal
https://learn.elastic.co/pages/58/home-page
試験で問われるポイント
- Async Search APIを利用し、非同期検索を実装できること
- Cross Cluster Search(CCS)でRemote Clusterを対象とした検索を実装できること
- Async Search、Cross Cluster Search、Query DSLを組み合わせた検索クエリを実装できること
Async SearchとCross Cluster Search(CCS)は、試験範囲の中では比較的難易度が高くない分野です。それぞれ1問程度出題される可能性がありますので、確実に実装できるよう繰り返し練習し、取りこぼしのないようにしておきましょう。


