ブログ

Kibana に Elasticsearch クエリルール UI を導入

Elasticsearch クエリ ルール UI を使用して、オーガニック ランキングに影響を与えずに Kibana のカスタマイズ可能なルールセットを使用して検索クエリにドキュメントを追加または除外する方法を学びます。

検索エンジンの役割は、関連性のある結果を返すことです。ただし、セールの強調、季節商品の優先、スポンサー商品の展示など、それ以上のビジネスニーズがあり、開発者は検索クエリでこれを常に実行できるとは限りません。

さらに、これらのユースケースは通常、時間に敏感であり、一般的な開発段階 (コード ブランチを作成してから新しいリリースを待つ) を実行するのは時間のかかるプロセスです。

では、このプロセス全体を API 呼び出しだけで、あるいは Kibana で数回クリックするだけで実行できたらどうなるでしょうか?

クエリルールUI

Elasticsearch 8.10 では、クエリ ルールルール リトリーバーが導入されました。これらは、ルールに基づいてオーガニック検索結果のランキングに影響を与えずに、ピン留めされた結果をクエリに挿入するように設計されたツールです。宣言的かつシンプルな方法で、結果の上にビジネス ロジックを追加するだけです。

クエリ ルールの一般的な使用例は次のとおりです。

  • プロモーション対象商品やセール品の強調表示: セール中の商品やスポンサー商品を上部に表示します。

  • コンテキストまたは地理位置情報による除外: 地域の規制により表示が許可されていない場合は、特定のアイテムを非表示にします。

  • 主要な結果を優先する: オーガニックランキングに関係なく、人気のある検索や固定検索が常に上位に表示されるようにします。

インターフェースにアクセスしてこれらのツールを操作するには、Kibana サイドメニューをクリックし、関連性の下にあるクエリルールに移動する必要があります

Elasticsearchの関連性に基づくクエリルールへのアクセス

クエリ ルール メニューが表示されたら、最初のルール セットの作成をクリックします。

Elasticsearchで最初のクエリルールルールセットを作成する

次に、ルールセットに名前を付ける必要があります。

Elasticsearch でのクエリルールのルールセットの命名

各ルールを定義するフォームには、次の 3 つの主要コンポーネントがあります。

  • 基準: ルールを適用するために満たす必要がある条件。たとえば、「query_string フィールドに値Christmasが含まれている場合」や「country フィールドにCO の場合」などです。

  • アクション: これは、条件が満たされたときに発生する動作です。ピン留め(ドキュメントを上位の結果に固定する)したり、除外(ドキュメントを非表示にする)したりできます。

  • メタデータ: これらはクエリの実行時にクエリに付随するフィールドです。これらには、ユーザーの情報 (場所や言語など) や検索データ (query_string) を含めることができます。これらは、ルールを適用するかどうかを決定するための基準で使用される値です。

例: 人気商品

さまざまな商品を扱う電子商取引サイトがあると想像してみましょう。指標をチェックすると、コンソール カテゴリで最も売れているアイテムの 1 つが「DualShock 4 ワイヤレス コントローラー」であることがわかります。特に、ユーザーが「PS4」または「PlayStation 4」というキーワードを検索した場合に多く見られます。そこで、ユーザーがこれらのキーワードを検索するたびに、この製品を結果の最上位に表示することにしました。

まず、Bulk API リクエストを使用して各アイテムのドキュメントをインデックス化します。

POST _bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "id": "1", "name": "PlayStation 4 Slim 1TB", "category": "console", "brand": "Sony", "price": 1200 }
{ "index": { "_index": "products", "_id": "2" } }
{ "id": "2", "name": "DualShock 4 Wireless Controller", "category": "accessory", "brand": "Sony", "price": 250 }
{ "index": { "_index": "products", "_id": "3" } }
{ "id": "3", "name": "PlayStation 4 Camera", "category": "accessory", "brand": "Sony", "price": 200 }
{ "index": { "_index": "products", "_id": "4" } }
{ "id": "4", "name": "PlayStation 4 VR Headset", "category": "accessory", "brand": "Sony", "price": 900 }
{ "index": { "_index": "products", "_id": "5" } }
{ "id": "5", "name": "Charging Station for DualShock 4", "category": "accessory", "brand": "Sony", "price": 80 }

クエリに介入しない場合、アイテムは通常 4 番目の場所に表示されます。クエリは次のとおりです。

GET products/_search
{
 "query": {
   "match": {
     "name": "PlayStation 4"
   }
 }
}

そして結果はこちらです

{
 "took": 1,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 0.6973252,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "2",
       "_score": 0.08701137,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}

これを変更するためのクエリ ルールを作成しましょう。まず、次のようにルールセットに追加しましょう。

Elasticsearchでクエリルールのルールセットを編集する方法

または同等のAPI リクエスト:

PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-1232",
      "type": "pinned",
      "criteria": [
        {
          "type": "exact",
          "metadata": "query_string",
          "values": [
            "PS4",
            "PlayStation 4"
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}

クエリでルールセットを使用するには、クエリ ルール タイプを使用する必要があります。この種のクエリは、主に次の 2 つの部分で構成されます。

GET /products/_search
{
 "retriever": {
   "rule": {
     "retriever": {
       "standard": {
         "query": {
           "match": { "name": "PlayStation 4" }
         }
       }
     },
     "match_criteria": {
       "query_string": "PlayStation 4"
     },
     "ruleset_ids": ["my-rules"]
   }
 }
}
  • match_criteria : ユーザーのクエリと比較するために使用されるメタデータです。この例では、query_string フィールドの値が「PlayStation 4」の場合にルールセットがアクティブになります。

  • query : 検索してオーガニック検索結果を取得するために使用される実際のクエリ。

この方法では、最初にオーガニッククエリを実行し、次に Elasticsearch がルールセットのルールを適用します。

{
 "took": 17,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 1.7014122e+38,
   "hits": [
     {
       "_index": "products",
       "_id": "2",
       "_score": 1.7014122e+38,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}

例: ユーザーベースのメタデータ

クエリ ルールのもう 1 つの興味深い応用は、メタデータを使用して、ユーザーまたは Web ページからのコンテキスト情報に基づいて特定のドキュメントを表示することです。

たとえば、数値として表されるユーザーのロイヤルティ レベルに基づいて、アイテムやカスタマイズされたセールを強調表示したいとします。

これを実現するには、このメタデータをクエリに直接取り込んで、その値が特定の基準を満たしたときにルールがアクティブになるようにします。

まず、ロイヤルティ レベルの高いユーザーだけが閲覧できるドキュメントをインデックスします。

POST _bulk
{ "index": { "_index": "products", "_id": "6" } }
{ "id": "6", "name": "PlayStation Plus Deluxe Card - 12 months", "category": "membership", "brand": "Sony", "price": 300 }

ここで、同じルールセット内に新しいルールを作成し、loyalty_level が 80 以上の場合にアイテムが結果の上部に表示されるようにします。

Elasticsearchでクエリルールのルールセットを編集する方法

ルールとルールセットを保存します。

同等の REST リクエストは次のとおりです。

PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "pin-premiun-user",
      "type": "pinned",
      "criteria": [
        {
          "type": "gte",
          "metadata": "loyalty_level",
          "values": [
            80
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "6"
          }
        ]
      }
    }
  ]
}

ここで、クエリを実行するときに、メタデータに新しいパラメータroyality_levelを含める必要があります。ルールの条件が満たされると、新しいドキュメントが結果の上部に表示されます。

たとえば、loyalty_level が 80 のクエリを送信する場合:

POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 80
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}

結果の上部にロイヤルティ ドキュメントが表示されます。

{
  "took": 31,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 1.7014122e+38,
    "hits": [
      {
        "_index": "products",
        "_id": "6",
        "_score": 1.7014122e+38,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      },
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      }
    ]
  }
}

以下の場合、ロイヤルティ レベルが 70 であるため、ルールは満たされず、アイテムは上部に表示されません。

POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 70
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}

結果は次のとおりです。

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 0.5054567,
    "hits": [
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      },
      {
        "_index": "products",
        "_id": "6",
        "_score": 0.3817649,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      }
    ]
  }
}

例: 即時除外

DualShock 4 ワイヤレス コントローラー (ID 2)が一時的に入手できず、販売できないとします。そのため、ビジネス チームは、ドキュメントを手動で削除したり、何らかのデータ処理が開始されるのを待ったりする代わりに、当面は検索結果からドキュメントを削除することにしました。

先ほど人気アイテムに適用したのと同様のプロセスを使用しますが、今回は[Pinned]ではなく[Exclude]を選択します。このルールは一種のブラックリストとして機能します。クエリが実行されるたびに除外が機能するように、条件を「常時」に変更します。

ルールは次のようになります。

Elasticsearch の即時除外ルールセットの例

変更を適用するには、ルールとルールセットを保存します。同等の REST リクエストは次のとおりです。

PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-6358",
      "type": "pinned",
      "criteria": [
        {
          "type": "always"
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}

ここで、クエリを再度実行すると、以前のルールではアイテムをピン留めするはずだったにもかかわらず、アイテムが結果に表示されなくなっていることがわかります。これは、除外がピン留め結果よりも優先されるためです。

{
 "took": 6,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 4,
     "relation": "eq"
   },
   "max_score": 2.205655,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 2.205655,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 1.9738505,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 1.9738505,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.69247496,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}

まとめ

クエリ ルールを使用すると、コードを変更することなく関連性を簡単に調整できます。新しいKibana UIでは、 これらの変更を数秒で行うことができるため、お客様とビジネス チームは検索結果をより細かく制御できるようになります。

クエリ ルールは、電子商取引以外にも、サポート ポータルでトラブルシューティング ガイドを強調表示したり、ナレッジ ベースで重要な社内ドキュメントを表示したり、ニュース サイトで最新ニュースを宣伝したり、期限切れの求人やコンテンツの一覧を除外したりするなど、さまざまなシナリオで活用できます。ユーザーの役割や地域によって制限されたコンテンツを非表示にするなど、コンプライアンス ルールを適用することもできます。

関連記事

Elasticsearch の異なるバージョン間およびクラスター間でデータを移行する方法

Kofi Bartlett

JavaScript で Elasticsearch を正しく使う方法、パート II

Jeffrey Rengifo

セマンティック検索の実装: Elasticsearch を使ったレシピ検索の構築

Andre Luiz

AWS MarketplaceでElasticsearchをデプロイする方法

Eduard Martin

Azure AKS Automatic に Elasticsearch をデプロイする方法

Eduard Martin

最先端の検索体験を構築する準備はできましたか?

十分に高度な検索は 1 人の努力だけでは実現できません。Elasticsearch は、データ サイエンティスト、ML オペレーター、エンジニアなど、あなたと同じように検索に情熱を傾ける多くの人々によって支えられています。ぜひつながり、協力して、希望する結果が得られる魔法の検索エクスペリエンスを構築しましょう。

はじめましょう