Azure Cognitive Search でファセット フィルターを作成する方法How to build a facet filter in Azure Cognitive Search

ファセット ナビゲーションは、検索アプリでクエリ結果をユーザー自身がフィルター処理するために使用されます。ご自身のアプリケーションに、(カテゴリやブランドなど) ドキュメントのグループを検索範囲として指定する UI コントロールがあり、Azure Cognitive Search にこのエクスペリエンスを支えるデータ構造があります。Faceted navigation is used for self-directed filtering on query results in a search app, where your application offers UI controls for scoping search to groups of documents (for example, categories or brands), and Azure Cognitive Search provides the data structure to back the experience. この記事では、提供する検索エクスペリエンスを支えるファセット ナビゲーション構造の基本的な作成手順を簡単に説明します。In this article, quickly review the basic steps for creating a faceted navigation structure backing the search experience you want to provide.

  • フィルターとファセットに適したフィールドを選択するChoose fields for filtering and faceting
  • フィールドに属性を設定するSet attributes on the field
  • インデックスを作成し、データを読み込むBuild the index and load data
  • クエリへのファセット フィルターの追加Add facet filters to a query
  • 結果を処理するHandle results

ファセットは動的であり、クエリで返されます。Facets are dynamic and returned on a query. 検索の応答で、結果のナビゲートに使用されるファセット カテゴリが提供されます。Search responses bring with them the facet categories used to navigate the results. ファセットの知識がない場合、次の例はファセット ナビゲーション構造を示しています。If you aren't familiar with facets, the following example is an illustration of a facet navigation structure.

フィルター処理された検索結果

検索ダイアログを示す図。フィルター処理された検索結果が肩書でグループ化されています。"An image showing a search dialog with filtered search results grouped by business title. 矢印は、結果がファセット ナビゲーション構造に表示されるファセットであることを示しています。:::image-end:::An arrow indicates the results are facets that are displayed in a facet navigation structure" :::image-end:::

ファセット ナビゲーションを初めて使用する場合、詳細については、New to faceted navigation and want more detail? Azure Cognitive Search へのファセット ナビゲーションの実装方法に関するページを参照してください。See How to implement faceted navigation in Azure Cognitive Search.

フィールドの選択Choose fields

ファセットは、単一値フィールドとコレクションで計算できます。Facets can be calculated over single value fields as well as collections. ファセット ナビゲーションに最適なのは、カーディナリティが低い (検索コーパス内のドキュメント (色、国/地域、またはブランド名のリストなど) 全体にわたって繰り返される異なる値が少ない) フィールドです。Fields that work best in faceted navigation have low cardinality: a small number of distinct values that repeat throughout documents in your search corpus (for example, a list of colors, countries/regions, or brand names).

ファセットは、インデックスの作成時に facetable 属性を true に設定することで、フィールドごとに有効になります。Faceting is enabled on a field-by-field basis when you create the index by setting the facetable attribute to true. 通常、エンド ユーザーが選択したファセットに基づいて検索アプリケーションがこのようなフィールドでフィルター処理を行うことができるように、これらのフィールドの filterable 属性も true に設定する必要があります。You should generally also set the filterable attribute to true for such fields so that your search application can filter on those fields based on facets that the end user selects.

REST API を使用してインデックスを作成すると、ファセット ナビゲーションで使用される可能性があるすべてのフィールドの型が、既定で facetable とマークされます。When creating an index using the REST API, any field type that could possibly be used in faceted navigation is marked as facetable by default:

  • Edm.String
  • Edm.DateTimeOffset
  • Edm.Boolean
  • 数値フィールドの型: Edm.Int32Edm.Int64Edm.DoubleNumeric field types: Edm.Int32, Edm.Int64, Edm.Double
  • 上記の型のコレクション (例: Collection(Edm.String) または Collection(Edm.Double))Collections of the above types (for example, Collection(Edm.String) or Collection(Edm.Double))

ファセット ナビゲーションでは、Edm.GeographyPoint フィールドや Collection(Edm.GeographyPoint) フィールドを使用することはできません。You cannot use Edm.GeographyPoint or Collection(Edm.GeographyPoint) fields in faceted navigation. ファセットはカーディナリティが低いフィールドで最適に機能します。Facets work best on fields with low cardinality. 地理座標の解像度が原因で、特定のデータセット内で任意の 2 つの座標セットが等しくなることはまれです。Due to the resolution of geo-coordinates, it is rare that any two sets of co-ordinates will be equal in a given dataset. そのため、ファセットは地理座標ではサポートされていません。As such, facets are not supported for geo-coordinates. 場所でファセットするには、都市フィールドまたは地域フィールドが必要です。You would need a city or region field to facet by location.

属性の設定Set attributes

フィールドの使用方法を制御するインデックスの属性は、インデックス内の個々 のフィールド定義に追加されます。Index attributes that control how a field is used are added to individual field definitions in the index. 次の例では、ファセットに有用な、カーディナリティが低いフィールドは、category (hotel、motel、hostel)、tagsrating で構成されています。In the following example, fields with low cardinality, useful for faceting, consist of: category (hotel, motel, hostel), tags, and rating. 次の例では、わかりやすいように、これらのフィールドには filterable および facetable 属性が明示的に設定されています。These fields have the filterable and facetable attributes set explicitly in the following example for illustrative purposes.

ヒント

パフォーマンスとストレージの最適化のためのベスト プラクティスとして、ファセットとして使用されることのないフィールドではファセットを無効にします。As a best practice for performance and storage optimization, turn faceting off for fields that should never be used as a facet. 具体的には、ID や製品名などの一意の値の文字列フィールドは、ファセット ナビゲーションで誤って (無駄に) 使用されないように、"facetable": false に設定する必要があります。In particular, string fields for unique values, such as an ID or product name, should be set to "facetable": false to prevent their accidental (and ineffective) use in faceted navigation.

{
  "name": "hotels",  
  "fields": [
    { "name": "hotelId", "type": "Edm.String", "key": true, "searchable": false, "sortable": false, "facetable": false },
    { "name": "baseRate", "type": "Edm.Double" },
    { "name": "description", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false },
    { "name": "description_fr", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false, "analyzer": "fr.lucene" },
    { "name": "hotelName", "type": "Edm.String", "facetable": false },
    { "name": "category", "type": "Edm.String", "filterable": true, "facetable": true },
    { "name": "tags", "type": "Collection(Edm.String)", "filterable": true, "facetable": true },
    { "name": "parkingIncluded", "type": "Edm.Boolean",  "filterable": true, "facetable": true, "sortable": false },
    { "name": "smokingAllowed", "type": "Edm.Boolean", "filterable": true, "facetable": true, "sortable": false },
    { "name": "lastRenovationDate", "type": "Edm.DateTimeOffset" },
    { "name": "rating", "type": "Edm.Int32", "filterable": true, "facetable": true },
    { "name": "location", "type": "Edm.GeographyPoint" }
  ]
}

注意

このインデックス定義は、REST API を使用した Azure Cognitive Search インデックスの作成に関する記事からコピーしたものです。This index definition is copied from Create an Azure Cognitive Search index using the REST API. フィールド定義の表面的な違い以外は全く同じです。It is identical except for superficial differences in the field definitions. categorytagsparkingIncludedsmokingAllowed、および rating フィールドに filterable および facetable 属性がで明示的に追加されています。The filterable and facetable attributes are explicitly added on category, tags, parkingIncluded, smokingAllowed, and rating fields. REST API を使用する場合、実際には、filterable および facetable はこれらのフィールドでは既定で有効になります。In practice, filterable and facetable would be enabled by default on these fields when using the REST API. .NET SDK を使用する場合、これらの属性は明示的に有効にする必要があります。When using the .NET SDK, these attributes must be enabled explicitly.

インデックスの作成と読み込みBuild and load an index

(言うまでもありませんが) 中間の手順として、クエリを作成する前にインデックスを作成して設定する必要があります。An intermediate (and perhaps obvious) step is that you have to build and populate the index before formulating a query. ここでは、完全を期すためにこの手順に触れました。We mention this step here for completeness. インデックスを使用できるかどうかを判断する 1 つの方法として、ポータルでインデックスの一覧を確認します。One way to determine whether the index is available is by checking the indexes list in the portal.

クエリへのファセット フィルターの追加Add facet filters to a query

アプリケーション コードでは、有効なクエリのすべての部分 (検索式、ファセット、フィルター、スコアリング プロファイルなど、要求の作成に使用されるすべてのもの) を指定するクエリを作成します。In application code, construct a query that specifies all parts of a valid query, including search expressions, facets, filters, scoring profiles– anything used to formulate a request. 次の例では、宿泊施設の種類、評価、他のアメニティに基づいてファセット ナビゲーションを作成する要求を作成します。The following example builds a request that creates facet navigation based on the type of accommodation, rating, and other amenities.

var sp = new SearchParameters()
{
    ...
    // Add facets
    Facets = new[] { "category", "rating", "parkingIncluded", "smokingAllowed" }.ToList()
};

クリック イベントでフィルター処理された結果を返すReturn filtered results on click events

エンド ユーザーがファセット値をクリックすると、クリック イベントのハンドラーはフィルター式を使用してユーザーの意図を実現します。When the end user clicks on a facet value, the handler for the click event should use a filter expression to realize the user's intent. $filter ファセットの場合、"motel" というカテゴリのクリックは、この種類の宿泊施設を選択する category 式によって実装されます。Given a category facet, clicking the category "motel" is implemented with a $filter expression that selects accommodations of that type. ユーザーが "motel" をクリックしてモーテルだけを表示するように指示すると、アプリケーションが送信する次のクエリに $filter=category eq 'motel' が含まれます。When a user clicks "motel" to indicate that only motels should be shown, the next query the application sends includes $filter=category eq 'motel'.

次のコード スニペットでは、ユーザーがカテゴリ ファセットから値を選択した場合に、カテゴリをフィルターに追加します。The following code snippet adds category to the filter if a user selects a value from the category facet.

if (!String.IsNullOrEmpty(categoryFacet))
    filter = $"category eq '{categoryFacet}'";

ユーザーが tags のようなコレクション フィールドのファセット値 (例: "pool" という値) をクリックすると、アプリケーションでは $filter=tags/any(t: t eq 'pool') というフィルター構文が使用されます。If the user clicks on a facet value for a collection field like tags, for example the value "pool", your application should use the following filter syntax: $filter=tags/any(t: t eq 'pool')

ヒントと対処方法Tips and workarounds

ファセットが設定されたページを初期化するInitialize a page with facets in place

ファセットが設定されたページを初期化する場合は、ページの初期化の一環としてクエリを送信して、初期ファセット構造でページをシードできます。If you want to initialize a page with facets in place, you can send a query as part of page initialization to seed the page with an initial facet structure.

フィルター処理された結果のファセット ナビゲーション構造を非同期に保持するPreserve a facet navigation structure asynchronously of filtered results

Azure Cognitive Search のファセット ナビゲーションの課題の 1 つは、現在の結果に対してのみファセットが存在することです。One of the challenges with facet navigation in Azure Cognitive Search is that facets exist for current results only. 実際には、手順を遡って検索コンテンツで代替パスを探索することで、ユーザーが逆方向にナビゲートできるようにファセットの静的なセットを保持するのが一般的です。In practice, it's common to retain a static set of facets so that the user can navigate in reverse, retracing steps to explore alternative paths through search content.

これは一般的なユース ケースですが、現時点ではファセット ナビゲーション構造ですぐに利用できるものではありません。Although this is a common use case, it's not something the facet navigation structure currently provides out-of-the-box. 静的なファセットを必要とする開発者は、通常、結果に適用されるクエリと、ナビゲーションのためにファセットの静的リストの作成に使用されるクエリの 2 つのフィルター処理されたクエリを発行してこの制限に対処しています。Developers who want static facets typically work around the limitation by issuing two filtered queries: one scoped to the results, the other used to create a static list of facets for navigation purposes.

関連項目See also