Elasticsearchの詳細-Scrollスクロールクエリー

6917 ワード

Scroll searchは単一の結果「ページ」を返すことを要求し、scroll APIは、従来のデータベースで使用されているカーソルcursorのように、大量の結果(さらにはすべての結果)を取得するために使用することができる.
スクロールは、リアルタイムのユーザ応答のためではなく、例えば、異なる構成を使用して1つのindexを別のindexに再インデックスするために、大量のデータを処理するためです.
Clientサポート:PerlとPython
注:scrollリクエストから返された結果は、スナップショットのようなsearchの発生時刻のインデックス状態を反映します.後続のドキュメントの変更(インデックス、更新、または削除)は、後続の検索要求にのみ影響します.
scrollを使用するには、最初の検索要求は、scrollパラメータをクエリーに指定する必要があります.これは、?scroll=1mのような検索のコンテキスト環境をどのくらい維持する必要があるかを示すことができます(Keeping the search context aliveを参照).
POST /twitter/tweet/_search?scroll=1m 
{
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}

上記の要求を使用して返された結果には、scroll_idが含まれており、このIDは、scroll APIに渡されて次のロットの結果を取得することができる.
POST /_search/scroll
{
    "scroll" : "1m", 
    "scroll_id" : "c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1" 
}
  • GETまたはPOSTは、
  • を用いることができる.
  • URLは、indexまたはtypeの名前を含むべきではありません.これらは、元のsearchリクエストに指定されています.
  • scrollパラメータは、Elasticsearchが検索を保持するコンテキストが別の1m
  • を待つことを示す.
  • scroll_idパラメータ
  • scroll APIの呼び出しが結果を返すたびに、次のバッチは、hits配列が空になるまで、より多くの結果が返されないことを知っている.
    前方互換性のために、scroll_idおよびscrollをクエリー文字列に配置して渡すことができる.scroll_idは、要求体において伝達することができる.
    curl -XGET 'localhost:9200/_search/scroll?scroll=1m' -d 'c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1'
    

    注意:初期検索要求および後続のスクロール要求は、最近の_scroll_idのみが使用できる新しい_scroll_idを返します.
    リクエストが集約(aggregation)を指定した場合、初期検索応答のみが集約結果を含む.
    scroll-scanを使用した効率的なスクロールfrom and sizeの深さページング、例えば?size=10&from=10000を使用することは、100,000の並べ替えの結果が各スライスから取り出され、並べ替えが最終的に10に戻る必要があるため、非常に非効率である.このプロセスは、要求ページごとに繰り返される必要があります.scroll APIは、記録された結果を保持しているので、より効率的にソートされた結果を返すことができる.ただし、デフォルトのソート結果には代価が必要です.
    一般的には、結果を見つけたいだけで、順序に関心がありません.scrollscanを組み合わせることで、スコアまたはソートをオフにして、最も効率的な方法で結果を返すことができます.search_type=scanをクエリーの文字列に追加する必要があります.
    POST /twitter/tweet/_search?scroll=1m&search_type=scan
    {
       "query": {
           "match" : {
               "title" : "elasticsearch"
           }
       }
    }
    
  • search_typescanに設定すると、スコアを閉じることができ、スクロールをより効率的にすることができます.

  • スキャンされたスクロール要求は、標準のスクロール要求とは大きく異なります.
  • はスコアを計算せず、ソートを閉じます.結果はインデックスに表示される順序で返されます.
  • は重合
  • をサポートしていない.
  • 初期search要求の応答は、hits配列に結果を含まない.最初の結果は、最初のscrollリクエストに従って返されます.
  • パラメータsizeは、各要求の結果の数ではなく、各スライスについて制御するので、size10の場合、5つのスライスがヒットした場合、scroll要求ごとに最大50の結果が返される.

  • 採点をサポートしたい場合は、ソートを行わなくてもtrack_scorestrueに設定します.
    検索コンテキストの生存を維持
    パラメータscroll(searchリクエストおよび各scrollリクエストに渡す)は、Elasticsearchが検索コンテキストをどのくらい維持する必要があるかを示す.この値(たとえば1m、詳細はthe section called「Time units」を参照)は、前のロットの結果を処理するのに十分な長さしか必要としないすべてのデータを処理する必要はありません.scrollリクエスト(scrollパラメータを含む)ごとに新しい失効時間が設定されます.
    一般に、背後にあるマージプロセスでは、より小さなセグメントをマージしてより大きなセグメントを作成することでインデックスを最適化し、より小さなセグメントを削除します.このプロシージャはスクロール時に実行されますが、開いた状態の検索コンテキストによって、古いセグメントが使用中に削除されないことが阻止されます.これがElasticsearchが後続の文書の変化にかかわらず、初期検索要求の結果を返すことができる理由である.
    古いセグメントを維持することは、より多くのファイルハンドルを生成することを意味します.ノードに空きファイルハンドルがあることを確認します.参考File Descriptors
    検索コンテキストが開いているかどうかを確認できます
    GET /_nodes/stats/indices/search?pretty
    

    scroll APIのクリア
    検索コンテキストは、scrollがタイムアウトすると自動的に削除されます.しかし、scrollの生存を維持するには代価が必要であり、前節で述べたように、scrollsはscrollが使用されなくなったときにclear-scrollで明示的にクリアする必要がある.
    DELETE /_search/scroll
    { 
      "scroll_id" : ["c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1"]
    }
    

    複数のscroll IDは、データに従って入力できます.
    DELETE /_search/scroll 
    { 
      "scroll_id" : ["c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1", "aGVuRmV0Y2g7NTsxOnkxaDZ"]
    }
    

    すべての検索コンテキストは、_allパラメータでクリアできます.
    DELETE /_search/scroll/_all
    
    scroll_idは、クエリ文字列のパラメータを使用するか、要求されたbodyに渡すこともできる.複数のscroll IDは、入力をカンマで区切ることができます.
    DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==,DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB
    

    Sliced Scroll 
    大量のドキュメントを返すスクロールクエリーでは、スクロールを複数のスライスに分割して、単独で使用できます.
    GET /twitter/_search?scroll=1m
    {
        "slice": {
            "id": 0, ①
            "max": 2 ②
        },
        "query": {
            "match" : {
                "title" : "elasticsearch"
            }
        }
    }
    GET /twitter/_search?scroll=1m
    {
        "slice": {
            "id": 1,
            "max": 2
        },
        "query": {
            "match" : {
                "title" : "elasticsearch"
            }
        }
    }

    スライスのid
    最大スライス数
    各スクロールは独立しており、スクロール要求のように並列に処理できます.最初のリクエストの結果は、最初のslice(id:0)に属するドキュメントを返し、2番目のリクエストの結果は、2番目のsliceに属するドキュメントを返します.最大スライス数が2に設定されているため、2つのリクエストの結果の和セットは、スライスされていないスクロールクエリの結果と同等です.デフォルトでは、まずshardセットで分割し、各shardで_を使用します.uidフィールドは、ローカルに分割され、その式は、例えば、shard数が2に等しく、ユーザが4つのsliceを要求する場合、分配シート0および2が第1のshardに、スライス1および3が第2のshardに割り当てられる.slice(doc) = floorMod(hashCode(doc._uid), max)の数がshardの数より大きい場合、スライスフィルタは、1回目の呼び出し時に非常に遅く、O(N)の複雑さを有し、メモリコストはsliceのN倍に等しく、Nはshard内のドキュメントの総数である.数回の呼び出しの後、キャッシュ・フィルタは後続の呼び出しでより高速になるはずですが、メモリオーバーフローを回避するために並列に実行されるスライス・クエリーの数を制限する必要があります.
    このようなコストを完全に回避するために、sliceの別のフィールドを使用してスライスを行うことができますが、ユーザーは、このフィールドに次の属性があることを確認する必要があります.
  • このフィールドは数値です.
  • doc_valuesこのフィールドで
  • を有効にする
  • 各ドキュメントには、単一の値が含まれます.ドキュメントに指定したフィールドの複数の値がある場合は、最初の値を使用します.
  • ドキュメントを作成しても、各ドキュメントの値は更新されません.これにより、各スライスが決定的な結果を得ることができる.
  • この分野の基数は高いはずです.これにより、スライスごとにほぼ同じ数のドキュメントが得られることが保証されます.
  • GET /twitter/_search?scroll=1m
    {
        "slice": {
            "field": "date",
            "id": 0,
            "max": 10
        },
        "query": {
            "match" : {
                "title" : "elasticsearch"
            }
        }
    }

    時間ベースのインデックスのみを追加する場合、doc_valuesは、このフィールドを安全に使用することができる.
    既定では、スクロールごとに許容する最大スライス数は1024に制限されています.この制限を回避するために、timestampインデックス設定を更新できます.