次の方法で共有


ファセットナビゲーションの例

このセクションでは、基本的な使用方法やその他のシナリオを示す例を使用して 、ファセット ナビゲーションの構成 を拡張します。

ファセット可能フィールドはインデックスで定義されますが、ファセット パラメーターと式はクエリ要求で定義されます。 ファセット可能なフィールドを持つインデックスがある場合は、既存のインデックスに対して ファセット階層ファセット集計ファセット フィルター などの新しいプレビュー機能を試すことができます。

ファセット パラメーターと構文

API に応じて、ファセット クエリは通常、検索結果に適用されるファセット式の配列です。 各ファセット式にはファセット可能なフィールド名が含まれ、オプションとしてその後にコンマで区切られた名前と値の組のリストが続きます。

  • ファセット クエリ は、ファセット プロパティを含むクエリ要求です。
  • facetable フィールド は、 facetable プロパティで属性付けされた検索インデックス内のフィールド定義です。
  • count は、検索結果で見つかった各ファセットの一致数です。

次の表では、例で使用されるファセット パラメーターについて説明します。

ファセット パラメーター Description Usage Example
count 構造体あたりのファセット用語の最大数。 整数。 既定値は 10 です。 上限はありませんが、値を大きくするとパフォーマンスが低下します。特に、ファセット フィールドに多数の一意の用語が含まれている場合です。 これは、ファセット クエリがシャード間で分散される方法が原因です。 count を 0 に設定するか、ファセット可能フィールド内の一意の値の数以上の値に設定して、すべてのシャードで正確なカウントを取得できます。 トレードオフは待機時間の増加です。 Tags,count:5 では、ファセット ナビゲーションの応答が、最も多くのファセット数を含む 5 つのファセット バケットに制限されますが、任意の順序で使用できます。
sort ファセット バケットの順序を決定します。 有効な値は、 count-countvalue-valueです。 countを使用して、ファセットを最大から最小に一覧表示します。 -countを使用して昇順 (最小から最大) で並べ替えます。 value を使用して、ファセット値をアルファベットおよび数字で昇順に並べ替えます。 -valueを使用して、値で降順に並べ替えます。 "facet=Category,count:3,sort:count" は、検索結果内のカテゴリごとの一致数に基づき、降順で並べられた上位3つのファセットバケットを取得します。 上位 3 つのカテゴリが Budget、Extended-Stay、Luxury、Budget のヒット数が 5、Extended-Stay が 6、Luxury が 4 の場合、ファセット バケットは延長ステイ、予算、ラグジュアリーとして順序付けられます。 もう 1 つの例は"facet=Rating,sort:-value"です。 可能なすべての評価に対して、値の降順でファセットが生成されます。 評価が 1 から 5 の場合、各評価に一致するドキュメントの数に関係なく、ファセットは 5、4、3、2、1 の順序になります。
values ファセット ラベルの値を提供します。 ファセット エントリ値の動的なセットを指定するために、パイプで区切られた数値または Edm.DateTimeOffset 値を設定します。 期待される結果を得るには、値を順番に昇順で示す必要があります。 "facet=baseRate,values:10 | 20" では、3 つのファセットバケットが生成されます。1 つは基本レートで 0 から 10 未満まで、もう 1 つは 10 から 20 未満まで、さらに 1 つは 20 以上です。 文字列 "facet=lastRenovationDate,values:2024-02-01T00:00:00Z" では、2024 年 2 月より前に改装されたホテル用と、2024 年 2 月 1 日以降に改装されたホテル用の 2 つのファセット バケットが生成されます。
interval 間隔としてグループ化できるファセットの間隔のシーケンスを指定します。 数値の場合は 0 より大きい整数の間隔。日付の時刻値の場合は、分、時、日、週、月、四半期、年。 "facet=baseRate,interval:100" では、サイズ 100 の基本レート範囲に基づいてファセット バケットが生成されます。 基本レートがすべて $60 から $600 の間にある場合、0 から 100、100-200、200-300、300-400、400-500、500 から 600 のファセット バケットがあります。 文字列 "facet=lastRenovationDate,interval:year" は、ホテルが改装された年ごとに 1 つのファセット バケットを生成します。
timeoffset 時間の境界を設定する際に考慮する UTC 時間オフセットを指定します。 ([+-]hh:mm, [+-]hhmm, or [+-]hh) に設定します。 使用する場合は、 timeoffset パラメーターを interval オプションと組み合わせる必要があります。これは、 Edm.DateTimeOffset型のフィールドに適用される場合のみです。 "facet=lastRenovationDate,interval:day,timeoffset:-01:00" は、01:00:00 UTC (ターゲット タイム ゾーンの午前 0 時) に始まる日の境界を使用します。

count sortは同じファセット仕様で結合できますが、intervalvaluesと組み合わせることはできません。

intervalvalues を組み合わせることはできません。

日付時刻の間隔ファセットは、 timeoffset が指定されていない場合、UTC 時刻に基づいて計算されます。 たとえば、 "facet=lastRenovationDate,interval:day"の場合、日の境界は UTC の 00:00:00 から始まります。

基本的なファセットの例

次のファセット クエリは 、hotels サンプル インデックスに対して機能します。 検索エクスプローラーで JSON ビュー を使用して、JSON クエリに貼り付けることができます。 作業の開始に関するヘルプについては、「 検索結果にファセット ナビゲーションを追加する」を参照してください。

この最初のクエリでは、特定の範囲の baseRate 値を持つカテゴリ、評価、タグ、ルームのファセットを取得します。 最後のファセットが Rooms コレクションのサブフィールドにあることに注意してください。 ファセットは、中間サブドキュメント (Rooms) ではなく親ドキュメント (ホテル) をカウントするため、応答によって、各価格カテゴリに部屋がある ホテル の数が決まります。

POST /indexes/hotels-sample-index/docs/search?api-version=2025-03-01-Preview
{  
  "search": "ocean view",  
  "facets": [ "Category", "Rating", "Tags", "Rooms/BaseRate,values:80|150|220" ],
  "count": true 
}  

この 2 番目の例では、フィルターを使用して、ユーザーが Rating 3 とカテゴリ "Motel" を選択した後で、前のファセット クエリ結果を絞り込みます。

POST /indexes/hotels-sample-index/docs/search?api-version=2025-03-01-Preview
{  
  "search": "water view",  
  "facets": [ "Tags", "Rooms/BaseRate,values:80|150|220" ],
  "filter": "Rating eq 3 and Category eq 'Motel'",
  "count": true  
} 

3 番目の例では、クエリで返される一意の用語の上限を設定します。 既定値は 10 ですが、ファセット属性の count パラメーターを使用して、この値を増減できます。 この例では、都市のファセットを取得し、その数を5に制限します。

POST /indexes/hotels-sample-index/docs/search?api-version=2025-03-01-Preview
{  
  "search": "view",  
  "facets": [ "Address/City,count:5" ],
  "count": true
} 

この例では、"Category"、"Tags"、"Rating" の 3 つのファセットを示し、"Tags" のカウント オーバーライドと "Rating" の範囲オーバーライドを示します。それ以外の場合は、インデックスに double として格納されます。

POST https://{{service_name}}.search.windows.net/indexes/hotels/docs/search?api-version={{api_version}}
{
    "search": "*",
    "facets": [ 
        "Category", 
        "Tags,count:5", 
        "Rating,values:1|2|3|4|5"
    ],
    "count": true
}

ファセット ナビゲーション ツリーごとに、クエリによって検出された上位 10 個のファセット インスタンスの既定の制限があります。 この既定値は、値リストを管理可能なサイズに保持するため、ナビゲーション構造に適しています。 値を "count" に割り当てることで、既定値をオーバーライドできます。 たとえば、 "Tags,count:5" では、[タグ] セクションのタグの数が上位 5 に減ります。

数値と DateTime の値の場合のみ、ファセット フィールド (たとえば、 facet=Rating,values:1|2|3|4|5) に値を明示的に設定して、結果を連続する範囲 (数値または期間に基づく範囲) に分割できます。 または、 facet=Rating,interval:1のように"interval"を追加することもできます。

各範囲は、開始点として 0 を使用し、一覧の値をエンドポイントとして使用し、前の範囲をトリミングして個別の間隔を作成します。

個別の値の例

各ファセット可能フィールドの個別の値のカウントを返すクエリを作成できます。 この例では、すべてのドキュメントに一致する空のクエリまたは非修飾クエリ ("search": "*") を作成しますが、 top を 0 に設定すると、結果なしでカウントだけが取得されます。

簡潔にするために、このクエリには、hotels サンプル インデックスに facetable としてマークされた 2 つのフィールドだけが含まれます。

POST https://{{service_name}}.search.windows.net/indexes/hotels/docs/search?api-version={{api_version}}
{
    "search": "*",
    "count": true,
    "top": 0,
    "facets": [ 
        "Category", "Address/StateProvince""
    ]
}

このクエリの結果は次のとおりです。

{
  "@odata.count": 50,
  "@search.facets": {
    "Address/StateProvince": [
      {
        "count": 9,
        "value": "WA"
      },
      {
        "count": 6,
        "value": "CA "
      },
      {
        "count": 4,
        "value": "FL"
      },
      {
        "count": 3,
        "value": "NY"
      },
      {
        "count": 3,
        "value": "OR"
      },
      {
        "count": 3,
        "value": "TX"
      },
      {
        "count": 2,
        "value": "GA"
      },
      {
        "count": 2,
        "value": "MA"
      },
      {
        "count": 2,
        "value": "TN"
      },
      {
        "count": 1,
        "value": "AZ"
      }
    ],
    "Category": [
      {
        "count": 13,
        "value": "Budget"
      },
      {
        "count": 12,
        "value": "Suite"
      },
      {
        "count": 7,
        "value": "Boutique"
      },
      {
        "count": 7,
        "value": "Resort and Spa"
      },
      {
        "count": 6,
        "value": "Extended-Stay"
      },
      {
        "count": 5,
        "value": "Luxury"
      }
    ]
  },
  "value": []
}

ファセット階層の例

現在、この機能はパブリック プレビュー段階にあります。 このプレビュー版はサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳細については、「 Microsoft Azure プレビューの追加使用条件」を参照してください。

2025-03-01-preview REST API 以降、Azure portal で使用できるように、>演算子と;演算子を使用してファセット階層を構成できます。

Operator Description
> 入れ子 (階層) 演算子は、親子関係を表します。
; セミコロン演算子は、同じ親のすべての子である同じ入れ子レベルの複数のフィールドを表します。 親にはフィールドが 1 つだけ含まれる必要があります。 親フィールドと子フィールドの両方を facetableする必要があります。

ファセット階層を含むファセット式における操作の順序は次のとおりです。

  • ファセットフィールドのファセットパラメーターをコンマ (,) で区切る options演算子ですが、その例としては Rooms/BaseRate,values などがあります。
  • 括弧とは、(Rooms/BaseRate,values:50 ; Rooms/Type)を囲むときに使用されるようなものです。
  • 入れ子演算子 (山かっこ >)
  • 追加演算子 (セミコロン ;): このセクションの 2 番目の例の "Tags>(Rooms/BaseRate,values:50 ; Rooms/Type)" で示されており、2 つの子ファセットは Tags という親の下で対等の関係にあります。

括弧は、入れ子操作や追加操作に優先して処理されます: A > B ; CA > (B ; C) と異なります。

ファセット階層にはいくつかの例があります。 最初の例は、いくつかのドキュメントのみを返すクエリであり、完全な応答を表示するのに役立ちます。 ファセットは親ドキュメント (Hotels) をカウントし、中間サブドキュメント (Rooms) はカウントしないため、応答によって、各ファセット バケットに部屋がある ホテル の数が決まります。

POST /indexes/hotels-sample-index/docs/search?api-version=2025-03-01-Preview
{
  "search": "ocean",  
  "facets": ["Address/StateProvince>Address/City", "Tags>Rooms/BaseRate,values:50"],
  "select": "HotelName, Description, Tags, Address/StateProvince, Address/City",
  "count": true 
}

このクエリの結果は次のとおりです。 どちらのホテルにもプールがあります。 その他のタグについては、アメニティを提供するホテルは 1 つだけです。

{
  "@odata.count": 2,
  "@search.facets": {
    "Tags": [
      {
        "value": "pool",
        "count": 2,
        "@search.facets": {
          "Rooms/BaseRate": [
            {
              "to": 50,
              "count": 0
            },
            {
              "from": 50,
              "count": 2
            }
          ]
        }
      },
      {
        "value": "air conditioning",
        "count": 1,
        "@search.facets": {
          "Rooms/BaseRate": [
            {
              "to": 50,
              "count": 0
            },
            {
              "from": 50,
              "count": 1
            }
          ]
        }
      },
      {
        "value": "bar",
        "count": 1,
        "@search.facets": {
          "Rooms/BaseRate": [
            {
              "to": 50,
              "count": 0
            },
            {
              "from": 50,
              "count": 1
            }
          ]
        }
      },
      {
        "value": "restaurant",
        "count": 1,
        "@search.facets": {
          "Rooms/BaseRate": [
            {
              "to": 50,
              "count": 0
            },
            {
              "from": 50,
              "count": 1
            }
          ]
        }
      },
      {
        "value": "view",
        "count": 1,
        "@search.facets": {
          "Rooms/BaseRate": [
            {
              "to": 50,
              "count": 0
            },
            {
              "from": 50,
              "count": 1
            }
          ]
        }
      }
    ],
    "Address/StateProvince": [
      {
        "value": "FL",
        "count": 1,
        "@search.facets": {
          "Address/City": [
            {
              "value": "Tampa",
              "count": 1
            }
          ]
        }
      },
      {
        "value": "HI",
        "count": 1,
        "@search.facets": {
          "Address/City": [
            {
              "value": "Honolulu",
              "count": 1
            }
          ]
        }
      }
    ]
  },
  "value": [
    {
      "@search.score": 1.6076145,
      "HotelName": "Ocean Water Resort & Spa",
      "Description": "New Luxury Hotel for the vacation of a lifetime. Bay views from every room, ___location near the pier, rooftop pool, waterfront dining & more.",
      "Tags": [
        "view",
        "pool",
        "restaurant"
      ],
      "Address": {
        "City": "Tampa",
        "StateProvince": "FL"
      }
    },
    {
      "@search.score": 1.0594962,
      "HotelName": "Windy Ocean Motel",
      "Description": "Oceanfront hotel overlooking the beach features rooms with a private balcony and 2 indoor and outdoor pools. Inspired by the natural beauty of the island, each room includes an original painting of local scenes by the owner. Rooms include a mini fridge, Keurig coffee maker, and flatscreen TV. Various shops and art entertainment are on the boardwalk, just steps away.",
      "Tags": [
        "pool",
        "air conditioning",
        "bar"
      ],
      "Address": {
        "City": "Honolulu",
        "StateProvince": "HI"
      }
    }
  ]
}

この 2 番目の例では、前の例を拡張し、複数の子を持つ複数の最上位ファセットを示します。 セミコロン (;) 演算子は各子を区切ります。

POST /indexes/hotels-sample-index/docs/search?api-version=2025-03-01-Preview
{  
  "search": "+ocean",  
  "facets": ["Address/StateProvince > Address/City", "Tags > (Rooms/BaseRate,values:50 ; Rooms/Type)"],
  "select": "HotelName, Description, Tags, Address/StateProvince, Address/City",
  "count": true 
}  

簡潔にするためにトリミングされた部分応答には、部屋の基本料金と種類の子要素を含むタグが表示されます。 ホテルのサンプル インデックスでは、+ocean に一致する両方のホテルには、各種の部屋とプールがあります。

{
  "@odata.count": 2,
  "@search.facets": {
    "Tags": [
      {
        "value": "pool",
        "count": 2,
        "@search.facets": {
          "Rooms/BaseRate": [
            {
              "to": 50,
              "count": 0
            },
            {
              "from": 50,
              "count": 2
            }
          ],
          "Rooms/Type": [
            {
              "value": "Budget Room",
              "count": 2
            },
            {
              "value": "Deluxe Room",
              "count": 2
            },
            {
              "value": "Standard Room",
              "count": 2
            },
            {
              "value": "Suite",
              "count": 2
            }
          ]
        }}]},
  ...
}

この最後の例は、括弧が入れ子レベルにどのように影響するかを示す優先順位の規則を示しています。 ファセット階層をこの順序で返したいとします。

Address/StateProvince
  Address/City
    Category
    Rating

この階層を返すには、「住所/市区町村」の下でカテゴリと評価が同じ階層にあるクエリを作成します。

  { 
    "search": "beach",  
    "facets": [
        "Address/StateProvince > (Address/City > (Category ; Rating))"
        ],
    "select": "HotelName, Description, Tags, Address/StateProvince, Address/City",
    "count": true 
  }

最も内側のかっこを削除すると、優先順位ルールは > 演算子が ;前に評価されることを意味するため、Category と Rating は兄弟ではなくなります。

  { 
    "search": "beach",  
    "facets": [
        "Address/StateProvince > (Address/City > Category ; Rating)"
        ],
    "select": "HotelName, Description, Tags, Address/StateProvince, Address/City",
    "count": true 
  }

最上位の親は引き続き Address/StateProvince ですが、現在は Address/City と Rating が同じレベルになっています。

Address/StateProvince
  Rating
  Address/City
    Category

ファセットフィルターの例

現在、この機能はパブリック プレビュー段階にあります。 このプレビュー版はサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳細については、「 Microsoft Azure プレビューの追加使用条件」を参照してください。

2025-03-01-preview REST API 以降、Azure portal で使用できるように、ファセット フィルターを構成できます。

ファセットフィルターを使用すると、指定した正規表現に基づいてファセット値を絞り込むことができます。 2 つの新しいパラメーターは、ファセット フィールドに適用される正規表現を受け入れます。

  • includeTermFilter 正規表現に一致するものにファセット値をフィルター処理する
  • excludeTermFilter は、正規表現と一致しないファセット値にフィルター処理します。

ファセット文字列が両方の条件を満たす場合は、バケット文字列のセットが最初に excludeTermFilter で評価され、次に includeTermFilter で除外されるため、excludeTermFilterが優先されます。

正規表現に一致するファセット値のみが返されます。 これらのパラメーターは、文字列フィールドの他のファセット オプション ( countsort階層ファセットなど) と組み合わせることができます。

正規表現は JSON 文字列値内で入れ子になっているため、二重引用符 (") 文字と円記号 (\) 文字の両方をエスケープする必要があります。 正規表現自体はスラッシュ (/) で区切られます。 エスケープ パターンの詳細については、「 正規表現の検索」を参照してください。

次の例は、バックスラッシュ、二重引用符、正規表現構文文字などの正規表現の特殊文字をエスケープする方法を示しています。

{
    "search": "*", 
    "facets": ["name,includeTermFilter:/EscapeBackslash\\\OrDoubleQuote\\"OrRegexCharacter\\(/"] 
}

次に示すのは、Budget と Extended-Stay のホテルと一致し、Rating を各ホテル カテゴリの子要素とするファセット フィルターの例です。

POST /indexes/hotels-sample-index/docs/search?api-version=2025-03-01-Preview
{ 
    "search": "*", 
    "facets": ["(Category,includeTermFilter:/(Budget|Extended-Stay)/)>Rating,values:1|2|3|4|5"],
    "select": "HotelName, Category, Rating",
    "count": true 
} 

次の例は、省略された応答です (簡潔にするためにホテルドキュメントは省略されています)。

{
  "@odata.count": 50,
  "@search.facets": {
    "Category": [
      {
        "value": "Budget",
        "count": 13,
        "@search.facets": {
          "Rating": [
            {
              "to": 1,
              "count": 0
            },
            {
              "from": 1,
              "to": 2,
              "count": 0
            },
            {
              "from": 2,
              "to": 3,
              "count": 4
            },
            {
              "from": 3,
              "to": 4,
              "count": 5
            },
            {
              "from": 4,
              "to": 5,
              "count": 4
            },
            {
              "from": 5,
              "count": 0
            }
          ]
        }
      },
      {
        "value": "Extended-Stay",
        "count": 6,
        "@search.facets": {
          "Rating": [
            {
              "to": 1,
              "count": 0
            },
            {
              "from": 1,
              "to": 2,
              "count": 0
            },
            {
              "from": 2,
              "to": 3,
              "count": 4
            },
            {
              "from": 3,
              "to": 4,
              "count": 1
            },
            {
              "from": 4,
              "to": 5,
              "count": 1
            },
            {
              "from": 5,
              "count": 0
            }
          ]
        }
      }
    ]
  }, 
  "value": [  ALL 50 HOTELS APPEAR HERE ]
}

ファセット集計の例

現在、この機能はパブリック プレビュー段階にあります。 このプレビュー版はサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳細については、「 Microsoft Azure プレビューの追加使用条件」を参照してください。

2025-03-01-preview REST API 以降を Azure portal で使って、ファセットを集計できます。

ファセット集計を使用すると、ファセット値からメトリックを計算できます。 集計機能は、既存のファセット オプションと共に機能します。 サポートされているメトリックは、 sumのみです。 数値ファセットに metric: sum を追加すると、各バケットのすべての値が集計されます。

ドキュメントにそのフィールドの null が含まれている場合に使用する既定値を追加できます: "facets": [ "Rooms/SleepsCount, metric: sum, default:2"]。 ルームに Rooms/SleepsCount フィールドに null 値がある場合、既定値は欠損値に置き換われます。

数値データ型のファセット可能フィールドを合計できます (ベクトルと地理座標を除く)。

hotels-sample-index の使用例を次に示します。 Rooms/SleepsCount フィールドはファセット可能で数値であるため、このフィールドを選択して合計を示します。 そのフィールドを合計すると、ホテル全体の睡眠数が取得されます。 ファセットは、中間サブドキュメント (Rooms) ではなく親ドキュメント (ホテル) をカウントするので、応答はホテル全体のすべての部屋の SleepsCount を合計することを思い出してください。 このクエリでは、1 つのホテルの SleepsCount を合計するフィルターを追加します。

POST /indexes/hotels-sample-index/docs/search?api-version=2025-03-01-Preview

{ 
      "search": "*",
      "filter": "HotelId eq '41'",
      "facets": [ "Rooms/SleepsCount, metric: sum"],
      "select": "HotelId, HotelName, Rooms/Type, Rooms/SleepsCount",
      "count": true
}

クエリの応答は、次の例のようになります。 ウィンディオーシャンモデルは合計40名のゲストを収容できます。

{
  "@odata.count": 1,
  "@search.facets": {
    "Rooms/SleepsCount": [
      {
        "sum": 40.0
      }
    ]
  },
  "value": [
    {
      "@search.score": 1.0,
      "HotelId": "41",
      "HotelName": "Windy Ocean Motel",
      "Rooms": [
        {
          "Type": "Suite",
          "SleepsCount": 4
        },
        {
          "Type": "Deluxe Room",
          "SleepsCount": 2
        },
        {
          "Type": "Budget Room",
          "SleepsCount": 2
        },
        {
          "Type": "Budget Room",
          "SleepsCount": 2
        },
        {
          "Type": "Suite",
          "SleepsCount": 2
        },
        {
          "Type": "Standard Room",
          "SleepsCount": 2
        },
        {
          "Type": "Deluxe Room",
          "SleepsCount": 2
        },
        {
          "Type": "Suite",
          "SleepsCount": 2
        },
        {
          "Type": "Suite",
          "SleepsCount": 4
        },
        {
          "Type": "Standard Room",
          "SleepsCount": 4
        },
        {
          "Type": "Standard Room",
          "SleepsCount": 2
        },
        {
          "Type": "Deluxe Room",
          "SleepsCount": 2
        },
        {
          "Type": "Suite",
          "SleepsCount": 2
        },
        {
          "Type": "Standard Room",
          "SleepsCount": 2
        },
        {
          "Type": "Deluxe Room",
          "SleepsCount": 2
        },
        {
          "Type": "Deluxe Room",
          "SleepsCount": 2
        },
        {
          "Type": "Standard Room",
          "SleepsCount": 2
        }
      ]
    }
  ]
}

次のステップ

ツールと API の ファセット ナビゲーション構成 を見直し、コードでファセットを操作するための ベスト プラクティス を確認します。

C#: プレゼンテーション レイヤーのコードを含むファセット ナビゲーションの例については、 Web アプリに検索を追加 することをお勧めします。 サンプルには、フィルター、提案、オートコンプリートも含まれています。 プレゼンテーション レイヤーには JavaScript と React が使用されます。