ときどき起きる

だいたい寝ている

Pinned Queryを使って検索結果を固定する【翻訳】

Pinned Query とその使い方について

Pinned Queryは Elasticsearch 7.4 でリリースされた機能の一つで、1つもしくは複数の任意に選択された文書を他の文書に優先して表示する機能です。この機能は文書の関連度に影響されないため、文書を優先手近位表示したい場合や、検索者を特定の文書に導きたい場合などに利用することができます。

具体的には以下のようなユースケースが考えられます

  • ナレッジ検索の開発者が、クエリ毎に最もクリックされている記事を優先的に表示する。
  • 新しくリリースしたプロダクトの宣伝のために検索結果の上位に固定する。また、季節に応じたマーケティングのためにこの機能を利用する。

Pinned Query の実装方法

仮のプロダクトデータを使って Pinned Query を試してみましょう

仮データの登録

PUT product/_bulk
{ "index" : { "_id": "prod101" } }
{ "brand" : "Apple", "model" : "iphone 11", "price": 800 }
{ "index" : { "_id": "prod102" } }
{ "brand" : "Samsung", "model" : "galaxy m32", "price": 700 }
{ "index" : { "_id": "prod103"} }
{ "brand" : "Apple", "model" : "iphone 13", "price": 1000 }
{ "index" : { "_id": "prod104"} }
{ "brand" : "Apple", "model" : "iphone 12", "price": 900 }
{ "index" : { "_id": "prod104"} }
{ "brand" : "Apple", "model" : "iphone 7", "price": 400 }

Pinned Query を使わない検索

POST product/_search
{
 "query": {
   "match": {
     "model": "iphone"
   }
 }
}

レスポンス:

"hits": [
     {
       "_index": "product",
       "_id": "prod101",
       "_score": 0.2578291,
       "_source": {
         "brand": "Apple",
         "model": "iphone 11",
         "price": 800
       }
     },
     {
       "_index": "product",
       "_id": "prod103",
       "_score": 0.2578291,
       "_source": {
         "brand": "Apple",
         "model": "iphone 13",
         "price": 1000
       }
     },
     {
       "_index": "product",
       "_id": "prod104",
       "_score": 0.2578291,
       "_source": {
         "brand": "Apple",
         "model": "iphone 12",
         "price": 900
       }
     },
     {
       "_index": "product",
       "_id": "prod105",
       "_score": 0.2578291,
       "_source": {
         "brand": "Apple",
         "model": "iphone 7",
         "price": 400
       }
     }
   ]

この時点では検索結果は関連度に応じてランキングされており、最新の機種が上位に来ていません。ここで Pinned Query を用いることでどのように最新機種を優先的に表示できるか見てみましょう。

Pinned Query を利用した検索

ここでは、最新のiPhoneを優先的に表示しようとしています。

POST product/_search
{
 "query": {
   "pinned": {
     "ids": [ "prod103", "prod104"],
     "organic": {
       "match": {
         "model": "iphone"
       }
     }
   }
 }
}
Pinned Query のレスポンス

Elasticsearch からのレスポンスの上位に iPhone 13 と iPhone 12 がそれぞれ表示されており、その他のプロダクトはそれに続く形で返却されています。

"hits": [
     {
       "_index": "product",
       "_id": "prod103",
       "_score": 1.7014124e+38,
       "_source": {
         "brand": "Apple",
         "model": "iphone 13",
         "price": 1000
       }
     },
     {
       "_index": "product",
       "_id": "prod104",
       "_score": 1.7014122e+38,
       "_source": {
         "brand": "Apple",
         "model": "iphone 12",
         "price": 900
       }
     },
     {
       "_index": "product",
       "_id": "prod101",
       "_score": 0.2578291,
       "_source": {
         "brand": "Apple",
         "model": "iphone 11",
         "price": 800
       }
     },
     {
       "_index": "product",
       "_id": "prod105",
       "_score": 0.2578291,
       "_source": {
         "brand": "Apple",
         "model": "iphone 7",
         "price": 400
       }
     }
   ]

Pinned Query を複数インデックスに対して利用する方法

もし複数インデックスをまたいで検索詩たい場合、以下のようにインデックス名も合わせて指定してください。

GET /_search
{
 "query": {
   "pinned": {
     "docs": [
       {
         "_index": "product-01",
         "_id": "prod101"
       },
       {
         "_index": "product-01",
         "_id": "prod102"
       },
       {
         "_index": "product-02",
         "_id": "prod105"
       }
     ],
     "organic": {
       "match": {
         "model": "iphone"
       }
     }
   }
 }
}

Pinned Query では最大 100 id までしか指定できない点にご注意ください

Pinned Query で指定した文書が表示されないケース

Elasticsearch は何も指定しない場合関連度順に文書を返却します。一方日付順や在庫順など、任意の並び順を sort オプションで指定する場合も想定されますが、これらの並び順では関連度は無視されるため、Pinned Query で指定されたドキュメントは優先的に表示されません。

例として、お手頃な iPhone 7iPhone 11 を指定しつつ、値段が高い順で検索してみましょう。

POST product/_search
{
 "sort": [
   {
     "price": {
       "order": "desc"
     }
   }
 ],
 "query": {
   "pinned": {
     "ids": [ "prod105", "prod101"],
     "organic": {
       "match": {
         "model": "iphone"
       }
     }
   }
 }
}
レスポンス

想定としては Pinned Query で指定した iPhone 7iPhone 11 が優先的に表示されてほしいところですが、実際には値段順で結果が返却され Pinned Query は考慮されていないことがわかります。

"hits": [
     {
       "_index": "product",
       "_id": "prod103",
       "_score": null,
       "_source": {
         "brand": "Apple",
         "model": "iphone 13",
         "price": 1000
       },
       "sort": [
         1000
       ]
     },
     {
       "_index": "product",
       "_id": "prod104",
       "_score": null,
       "_source": {
         "brand": "Apple",
         "model": "iphone 12",
         "price": 900
       },
       "sort": [
         900
       ]
     },
     {
       "_index": "product",
       "_id": "prod101",
       "_score": null,
       "_source": {
         "brand": "Apple",
         "model": "iphone 11",
         "price": 800
       },
       "sort": [
         800
       ]
     },
     {
       "_index": "product",
       "_id": "prod105",
       "_score": null,
       "_source": {
         "brand": "Apple",
         "model": "iphone 7",
         "price": 400
       },
       "sort": [
         400
       ]
     }
   ]

Elasticsearch 8.10 にて Query Rule が追加されます(されました)【翻訳】

Elasticsearch 8.10 において、新たに Query Rule 機能が追加されました。Query Rule は検索クエリや検索クエリに含まれるコンテキスト情報に応じてクエリを書き換える機能です。

Query Rule とは?

Query Rule は通常 Elasticsearch の検索シーンにて考慮されるようなクエリに対する関連度とは別の観点から検索結果をカスタマイズする方法で、主に検索クエリに含まれる検索コンテキスト情報を用る機能です。これにより、ユーザは例えばマーケティングのキャンペーンやパーソナライゼーション、特定の領域に特化した検索体験の提供などをすべて Elasticsearch 単体にて提供可能となります。

サポートされているルールの種類

この Query Rule 機能の第一歩として、特定の文書を検索結果内で優先的に表示することが可能な Pinned query rules をサポートしました。

この用途としては例えば

  • ユーザが iPhone と検索した場合に、上位に最新機種を表示する
  • ユーザが iPhone と検索した場合に、他のブランドから販売されているオススメ商品を表示する
  • football という検索に対して、ユーザの居住地によって異なる検索結果を提供する
  • 重要なお知らせをユーザ全員の検索結果に表示するために利用する
  • 次の評価期間に関するお知らせを、マネージャ以外の全従業員の検索結果に表示する

等々が想定されます。

サポートされている検索条件の種類

Query Rule でサポートされているクエリへのマッチ条件は以下の通りです。 *1

  • exact : 想定されたクエリに完全一致
  • fuzzy : 想定されたクエリからの編集距離が一定以内
  • prefix : クエリが特定の文字列から始まる
  • suffix : クエリが特定の文字列で終わる
  • contains : クエリが特定の文字列を含む
  • lt : 値が指定されたもの未満
  • lte : 値が指定されたもの以下
  • gt : 値が指定されたものより大きい
  • gte : 値が指定されたもの以上
  • always : すべてのクエリにマッチする

サポートされている固定方法の種類

Pinned query rules では2種類の固定方法がサポートされています。*2

  • ids : 文書IDを指定して固定
  • docs : インデックス名と文書IDのペアを指定 (訳注: 複数インデックスをまたいで検索するユースケースなどで想定。)

Query Rule の利用方法について

Query Rule を利用する際には、以下のプロセスに従いルールを作成・適用してください

  1. (事前準備) 検索システムの管理者が1つ以上の Query Rule を含んだルールセットを作成する
  2. Query Rule 管理APIを用いて、作成したルールセットを Elasticsearch に登録する
  3. (検索時) Rule query を利用して検索する
  4. Elasticsearch が指定されたルールセットおよびクエリにマッチするルールを特定する
  5. マッチしたルールをルールセットに登録された順に適用する
  6. Query rewrite phase にて、pinned query に書き換えられる
  7. 検索クエリにマッチしたドキュメントが返却され、その際 pinned query にマッチしたドキュメントが優先的に並べられる

以下の画像はその動作を示したダイアグラムです

引用元: https://www.elastic.co/jp/blog/introducing-query-rules-elasticsearch-8-10

利用例

簡単な利用例を見てみましょう。また、Elasticsearch Labsに沿ってお試しいただくことも可能です。

とあるECサイトが新しく発売した PureJuice Pro というワイヤレス充電器を宣伝しようとしています。

インデックスは以下のドキュメントを含みます。

POST /products/_doc/us1
{
  "name": "PureJuice Pro",
  "description": "PureJuice Pro: Experience the pinnacle of wireless charging. Blending rapid charging tech with sleek design, it ensures your devices are powered swiftly and safely. The future of charging is here.",
  "price": 15.00,
  "currency": "USD",
  "plug_type": "B",
  "voltage": "120v"
}

POST /products/_doc/uk1
{
  "name": "PureJuice Pro - UK Compatible",
  "description": "PureJuice Pro: Redefining wireless charging. Seamlessly merging swift charging capabilities with a refined aesthetic, it guarantees your devices receive rapid and secure power. Welcome to the next generation of charging.",
  "price": 20.00,
  "currency": "GBP",
  "plug_type": "G",
  "voltage": "230V"
}

POST /products/_doc/eu1
{
  "name": "PureJuice Pro - Wireless Charger suitable for European plugs",
  "description": "PureJuice Pro: Elevating wireless charging. Combining unparalleled charging speeds with elegant design, it promises both rapid and dependable energy for your devices. Embrace the future of wireless charging.",
  "price": 18.00,
  "currency": "EUR",
  "plug_type": "C",
  "voltage": "230V"
}

この時、ワイヤレス充電器を検索するクエリは以下の通りです。

POST /products/_search
{
  "query": {
    "multi_match": {
      "query": "wireless charger",
      "fields": [ "name^5", "description" ]
    }
  }
}

Query Rule の管理

まず初めに、manage_search_query_rules 権限を持った管理者が以下のルールセットを登録します。

PUT /_query_rules/promotion-rules
{
  "rules": [
    {
      "rule_id": "us-charger",
      "type": "pinned",
      "criteria": [
        {
          "type": "contains",
          "metadata": "my_query",
          "values": ["wireless charger"]
        },
        {
          "type": "exact",
          "metadata": "country",
          "values": ["us"]
        }
      ],
      "actions": {
        "ids": [
          "us1"
        ]
      }
    },
    {
      "rule_id": "uk-charger",
      "type": "pinned",
      "criteria": [
        {
          "type": "contains",
          "metadata": "my_query",
          "values": ["wireless charger"]
        },
        {
          "type": "exact",
          "metadata": "country",
          "values": ["uk"]
        }
      ],
      "actions": {
        "ids": [
          "uk1"
        ]
      }
    }
  ]
}

このルールセットでは、以下の2つのルールを定義しました。 - ユーザがwireless chargerを検索しており、かつ US に居住している場合、US側のプロダクトを検索結果の上位に固定する - ユーザがwireless chargerを検索しているが UK に居住している場合、UK側のプロダクトを代わりに検索結果の上位に固定する

Tips: 実際の検索時には裏側で Pinned Query に変換される関係上、以下の制約に従う必要があります。

  • idsの利用と`docsは二者択一であり、同時に利用することはできません。管理観点からも、同一ルールセット内でどちらを利用するかを事前に決めておくことをお勧めします。
  • Pinned Query は最大100文書の固定までしかサポートされていません。Query Rule もこれに準拠します。

Query Rule を用いた検索

Query Rule を検索に適用するためには rule_query を利用して検索します。具体的には以下のようになります。

POST /products/_search
{
  "query": {
    "rule_query": {
      "organic": {
        "multi_match": {
          "query": "reliable wireless charger for iPhone",
          "fields": [
            "name^5",
            "description"
          ]
        }
      },
      "match_criteria": {
        "my_query": "reliable wireless charger for iPhone",
        "country": "us"
      },
      "ruleset_id": "promotion-rules"
    }
  }
}

このクエリは以下のパートから構成されます

  • 検索およびランキングを行う organicクエリ。もし query rule が何も適用されない場合、純粋にこのクエリが実行されます。
  • ルールセットを参照するクエリを指定する、match_criteria。例では2つの条件を指定しています。
    • ユーザが入力したクエリをそのまま伝達するためのmy_query
    • ユーザの居住地をIPから判別したcountry
  • どのルールセットを参照するかを指定するruleset_id

ルールセット内に登録されたルールを一つずつ確認すると、以下のルールが検索条件にマッチすることがわかります。

{
      "rule_id": "us-charger",
      "type": "pinned",
      "criteria": [
        {
          "type": "contains",
          "metadata": "my_query",
          "values": ["wireless charger"]
        },
        {
          "type": "exact",
          "metadata": "country",
          "values": ["us"]
        }
      ],
      "actions": {
        "ids": [
          "id1-us"
        ]
      }
    }

ここで、ルールが適用されるには定義されたすべてのcriteriaに適合する必要があることに注意してください。

最後に、検索クエリは実行される前に以下のような形に書き換えられます。

{
  "query": {
    "pinned": {
      "organic": {
        "query_string": {
          "query": "reliable wireless charger for iPhone"
        }
      },
      "ids": [
        "id1-us"
      ]
    }
  }
}

Elasticsearchは書き換えられた pinned query を利用して検索を行い、適合したプロダクトを優先的に返却します。

まとめ

本記事では Query Rule を用い、検索コンテキストに応じて文書を優先的に表示する方法を紹介しました。

検索技術勉強会 Search Engineering Tech Talk 2023 Winter で登壇しました

2023/12/20に開催されたSearch Engineering Tech Talk 2023 Winterで「言語モデルを用いたQuery Categorizationへの取り組み」というタイトルで発表しました。

資料 speakerdeck.com

イベントページ search-tech.connpass.com

なお、同内容のテックブログを英語・日本語にて所属先のアドベントカレンダーでも公開しています。 engineering.mercari.com

2023年振り返り

紅白を見ながら年の瀬を感じたので、サクッと今年を振り返る

よかったこと・よかったもの

  • Query Understanding for Search Engines輪読会を主催している
    • Query Understandingについては和書で纏まった知識が得られるものが無いが一人で読むには気力がいるので輪読会形式に
    • 情報検索Slackで募集したところ、数社のエンジニア + 大学教授で進めることになり面白い展開になっている
    • 本書自体が色々な論文を参照してサマったものなので、その解釈について分担しつつ進められるのは大変ありがたい
    • 一方で分量が多く現時点で4ヶ月継続しているので、春までにはケリを付けたい
  • Dellの40インチ曲面モニターを買った
  • デスクのサイズを大きくした(140cm × 70cm)
    • 整理整頓が得意ではないので机の上には充電器、本、マウス、キーボードと散乱しているが、広いので避ければ作業スペースを確保できるようになった
    • そもそもこのサイズないと40インチのモニター厳しいよね、と思ったのがきっかけだったけど正解
  • ダイビング用品が少しずつ揃ってきた
    • GoPro + ライトは一通り揃ったので映像を記録できるのがモチベーションとして非常に良い
  • 5年ぶりくらいに海外に出た
    • 2週間半ヨーロッパの北側数カ国を回る旅行をした
    • 芸術とは縁遠い自分だが妻の意向もあって7個ほど美術館・博物館を巡った結果、普段得られない刺激と一般教養をもっとつけたい気持ちとが湧いてきた
    • PCを持っていかなかったので、学生時代含めて直近約10年の中で一番コードを書かなかった期間になったのも良いリフレッシュに

反省

  • アウトプットをサボりがち
  • モチベーションに関係なく忙しい状況が長期間継続した
    • チーム的に潤沢にメンバーがいた状況から一点、色々な都合で一時期ガクッと人数が激減 + 仕事量は変わらずとにかく眼の前の課題をこなす期間が続いてしまった
    • その状況も最近は落ち着きつつあるので、上述の輪読会に得た知識などを活用する機会を創出したい
  • 副業に時間を割きすぎた
    • 面白いタスクだったので割と副業モリモリ入れたところ1月 - 8月まで土日をほぼ使う結果に
    • 夏頃にキッパリと稼働時間減らす旨を伝えて、以降プライベートに再び時間を割く時間を増やしたのはいい判断だったと我ながら思う
  • 一眼の軽くて良いレンズを持っていない
    • 今メインで使っているレンズはSigma28-70mm F2.8 DG DN
    • ヨーロッパ旅行中もこれを持っていったけど、約500gと少し重くiPhoneで打狂する場面がちょこちょこあったので、もう少し軽いレンズを来年は買いたい

来年も良いお年を👋

運用中のElasticsearchからRallyを用いて負荷試験トラックを作成する

本記事はElastic Stack (Elasticsearch) Advent Calendar 2022の24日目の記事です。


こんにちは、pakioです。

本エントリでは、Rallyを用いて運用中のElasticsearchから負荷試験トラックを作成する方法、並びに複数負荷試験結果の比較方法を紹介したいと思います。 また、環境やその他要因による成約が一部あるため、そのあたりについても合わせて後半で開設予定です。

本エントリは2022/12/14に実施されたElasticsearchJP #51 LT大会で発表したRallyで支えるバージョン追従を補足する内容になります。

speakerdeck.com

ちなみに録画を見るとわかりますが、私のRallyのイントネーションは確実に熊本なまりに影響されたもので正しいものではないと思います。正しいイントネーション何なんだろう。

はじめに - Rallyとは?

RallyとはElastic社が開発するElasticsearch向けのベンチマークツールです。ツール自体はPythonで開発されており、pipでインストールが可能です。

esrally.readthedocs.io

ベンチマークの実行のほかにも、過去のベンチマーク結果との比較や、Elasticsearchクラスタのセットアップや各種メトリクスの監視なども行ってくれる、まさにオールインワンなツールとなっています。

  • Setup and teardown of an Elasticsearch cluster for benchmarking
  • Management of benchmark data and specifications even across Elasticsearch versions
  • Running benchmarks and recording results
  • Finding performance problems by attaching so-called telemetry devices
  • Comparing performance results

今回のブログでは、その中でも自らのインデックスをもとに負荷試験を実施できる、create-track機能およびrace機能の紹介を行います。

カスタムトラックの作成

以降、Rally 2.7.0 documentationからの翻訳および引用を一部含みます。 Define Custom Workloads: Tracks - Rally 2.7.0 documentation

1. 既存インデックスからカスタムトラックを作成

既存クラスター内のインデックスからカスタムトラックを作成したい場合、create-trackコマンドを利用することで基本的な負荷試験トラックが作成可能です。

esrally create-track --track=acme --target-hosts=127.0.0.1:9200 --indices="products,companies" --output-path=~/tracks

また、ロギングやメトリクス等のインデックスの場合日付ごとのインデックスになっているケースなどもあるかと思いますが、Rallyでは-*を指定しパターンにマッチしたインデックスを取得することも可能です。

esrally create-track --track=acme --target-hosts=127.0.0.1:9200 --data-streams="metrics-*,logs-*" --output-path=~/tracks

上記コマンドを実行すると、指定したoutput-path内にファイルが出力されます。

$ find tracks/acme
tracks/acme
tracks/acme/companies-documents.json
tracks/acme/companies-documents.json.bz2
tracks/acme/companies-documents-1k.json
tracks/acme/companies-documents-1k.json.bz2
tracks/acme/companies.json
tracks/acme/products-documents.json
tracks/acme/products-documents.json.bz2
tracks/acme/products-documents-1k.json
tracks/acme/products-documents-1k.json.bz2
tracks/acme/products.json
tracks/acme/track.json

ここで、-1kサフィックス付きのデータが存在します。Rallyではデータ全件を使ったベンチマーク以外にトラックの挙動を確かめられるテストモードが実装されており、この-1kのついたデータはテストで利用されるデータとなります。テストとはいえ実際のドキュメントからサンプリングされたものではあるため、十分な信頼性ですね。

オプションについて

コマンドを実行する際、認証情報やタイムアウト値、コネクション数など様々なオプションが指定でき、client-optionsにカンマ区切り文字列で指定します。

以下はその一例です。

▽ 通信の圧縮、basic authを有効

esrally create-track --track=acme --target-hosts=127.0.0.1:9200 --indices="products,companies" --output-path=~/tracks --client-options="basic_auth_user:'elastic',basic_auth_password:'secret-password',http_compress:true"

オプション一覧については公式ドキュメントをご覧ください。 Command Line Reference - Rally 2.7.0 documentation

2. ベンチマークの実施

作成されたトラックを用いてベンチマークを実行するには、raceコマンドを実行します。

esrally race --distribution-version=7.14.1 --track-path=~/tracks/acme

また、テストモードを用いて小規模データで試しに実行したい場合は--test-modeを引数に追加します。

esrally race --distribution-version=7.14.1 --track-path=~/tracks/acme --test-mode

各distribution versionの初回実行時にはダウンロードが発生しますが、完了次第それをもとにElasticsearchクラスタが構築され、トラックが実行されます。

    ____        ____
   / __ \____ _/ / /_  __
  / /_/ / __ `/ / / / / /
 / _, _/ /_/ / / / /_/ /
/_/ |_|\__,_/_/_/\__, /
                /____/

[INFO] Race id is [e72a728e-067f-44c8-b2f6-d4fc20591999]
[INFO] Preparing for race ...
[INFO] Racing on track [wiki] and car ['defaults'] with version [7.14.0].

Running delete-index                                                           [100% done]
Running create-index                                                           [100% done]
Running cluster-health                                                         [100% done]
Running bulk                                                                   [100% done]
Running search                                                                 [100% done]

------------------------------------------------------
    _______             __   _____
   / ____(_)___  ____ _/ /  / ___/_________  ________
  / /_  / / __ \/ __ `/ /   \__ \/ ___/ __ \/ ___/ _ \
 / __/ / / / / / /_/ / /   ___/ / /__/ /_/ / /  /  __/
/_/   /_/_/ /_/\__,_/_/   /____/\___/\____/_/   \___/
------------------------------------------------------

|                                                         Metric |   Task |          Value |   Unit |
|---------------------------------------------------------------:|-------:|---------------:|-------:|
|                     Cumulative indexing time of primary shards |        |    0.0711667   |    min |
...
|                                                     error rate | search |    0           |      % |


--------------------------------
[INFO] SUCCESS (took 27 seconds)
--------------------------------

ここで、ログの初めに表示されるRace IDは各実行ごとにユニークな値となっており、結果比較の際には各Race IDの差分を表示する形となります。

3. トラックのカスタマイズ

1の手順を実行して作成されたトラックにはbulkのオペレーションしか入っていませんが、負荷試験の多くのケースでは検索クエリのパフォーマンスも見たいかと思います。
RallyではトラックのカスタマイズにPythonで書いたスクリプトも利用可能なため、その機能を用いて検索クエリを投げるタスクを追加してみます。

3.1 クエリの用意

実行したい任意のクエリを用意します。クエリログを取得している方はそこから、していない方は実行したい任意のクエリを用意してください。
先ほど作成したトラック内に任意のディレクトリを作成(ここではqueriesとしています)、そこにクエリをJSON形式で保存して下さい。

$ tree queries

queries
├── query_1.json
├── query_2.json
└── query_3.json

3.2 スクリプト/トラックの用意

次に、用意した任意のクエリをランダムに読み込み、実行するPythonスクリプトを用意します。 ここでRallyではファイル名に制約があるため、track.pyというファイル名で保存します。

https://gist.github.com/pakio/749d7be3ea41abf2377608abed6c84e9#file-track-py Custom benchmarking track and script for EsRally · GitHub

上記のプログラムでは、作成したパラメータソースをmy-custom-param-sourceとして定義しており、これをtrack.json内に新規で追加したsearchオペレーションのparam-sourceとして呼び出すことでクエリを実行しています。

4. 履歴の比較

過去に実行したRaceは、以下のコマンドで表示できます。

$ esrally list races

    ____        ____
   / __ \____ _/ / /_  __
  / /_/ / __ `/ / / / / /
 / _, _/ /_/ / / / /_/ /
/_/ |_|\__,_/_/_/\__, /
                /____/


Recent races:

Race ID                               Race Timestamp    Track    Challenge    Car       ES Version    Revision                                  Rally Version    Track Revision    Team Revision    User Tags
------------------------------------  ----------------  -------  -----------  --------  ------------  ----------------------------------------  ---------------  ----------------  ---------------  -----------
e72a728e-067f-44c8-b2f6-d4fc20591999  20221224T061228Z  wiki                  defaults  7.14.0        dd5a0a2acaa2045ff9624f3729fc8a6f40835aa1  2.7.0                              d38ad85
47060ac5-61b6-46a6-86b3-ff1ffd7dfc3f  20221224T060401Z  wiki                  defaults  7.12.0        78722783c38caa25a70982b5b042074cde5d3b3a  2.7.0                              d38ad85
863a7d4f-d217-4852-8268-bf95a831f0bb  20221224T052447Z  wiki                  defaults  7.12.0        
-------------------------------
[INFO] SUCCESS (took 0 seconds)
-------------------------------

1列目がRace IDとなっており、race間の差分は以下のコマンドで確認できます。

esrally compare --baseline={比較元となるraceid} --contender={比較先となるraceid}

実行すると、改善した項目については緑で、悪化した項目については赤でハイライトした比較結果を表示します。

実行結果

制約について

Rallyを動かすうえで、いくつか環境によって制約が発生するようですので、その一部のご紹介です。

M1/2 Macを利用する場合

M1/2 Macを利用される場合、7.16.0以前のバージョンを利用したい場合、Rallyによる自動クラスタ構築ではなく、自前でクラスタを準備する必要があります。

Rallyは環境のセットアップ時に、ElasticのdownloadsからzipファイルでElasticsearchをダウンロードし実行しています。このサイト上でM1用であるMACOS AARCH64対応バイナリが配布開始されているのは7.16.0以降となっているため、それ以前のバージョンを利用したい場合には注意が必要です。

6系以前と7系以降の互換性

Elasticsearchの6系以前と7系以降では、主にmapping type廃止の影響でトラックを共有することができません。そのため、マッピングやbulkの形式など、一部人手を加えて調整してあげる必要があります。

終わりに

今回のブログではRallyを用いたカスタムトラックの作成方法と結果の比較方法について紹介しました。
個人的な印象ですが、この1年でRallyユーザの方や日本語で書かれたブログ記事なども多く見かけるようになってきた感じがします。実際に使ってみても便利なツールなので、まだ使われていない方は一度試してみることをお勧めします。

また、いろいろ調べながら書いている中で、約4ヵ月前に似たような内容のテックブログがビザスクさんから公開されているのを見つけましたが、書き直す時間もないので書ききってしまいました。かなり詳細にオプション等も解説されていたので、もし本ブログで不足する内容があればビザスクさんのテックブログ、もしくは公式ドキュメントをご参照ください。

tech.visasq.com