Поделиться через


Примеры фасетной навигации

В этом разделе расширена фасетная конфигурация навигации с примерами, демонстрирующими базовое использование и другие сценарии.

Фасетные поля определяются в индексе, но параметры и выражения фасетов определяются в запросах. Если у вас есть индекс с полями фасетной таблицы, вы можете попробовать новые функции предварительной версии, такие как иерархии аспектов, агрегаты аспектов и фильтры аспектов для существующих индексов.

Параметры аспектов и синтаксис

В зависимости от API, запрос аспектов обычно представляет собой массив выражений аспектов, применяемых к результатам поиска. Каждое фасетное выражение содержит имя фасетируемого поля, за которым, при необходимости, следует список пар "имя-значение", разделенный запятыми.

  • запрос по аспектам — это запрос, содержащий свойство аспекта.
  • Поле facetable — это определение поля в индексе поиска, атрибутируемое свойством facetable .
  • число совпадений для каждого аспекта, найденного в результатах поиска.

В следующей таблице описаны параметры аспектов, используемые в примерах.

Фасетный параметр Описание Использование Пример
count Максимальное количество терминов аспекта для каждой структуры. Целое число. Значение по умолчанию: 10. Нет верхнего предела, но более высокие значения ухудшают производительность, особенно если фасетное поле содержит большое количество уникальных терминов. Это связано с тем, как фасетные запросы распределяются по шардам. Можно задать count значение нулю или значение, которое больше или равно количеству уникальных значений в поле фасетной таблицы, чтобы получить точное количество всех сегментов. Компромисс увеличивает задержку. Tags,count:5 ограничивает фасетную навигацию до 5 групп аспектов, содержащих наибольшее количество аспектов, но они могут находиться в любом порядке.
sort Определяет порядок контейнеров фасетов. Допустимые значения: count, -count, value, -value. Используйте count для перечисления аспектов от наибольшего до наименьшего. Используется -count для сортировки по возрастанию (наименьшее до наибольшего). Используйте value для сортировки по фасетному значению в буквенно-цифровом порядке возрастания. Используется -value для сортировки по убыванию по значению. "facet=Category,count:3,sort:count" получает первые три сегмента аспектов в результатах поиска, перечисленных в порядке убывания по количеству совпадений в каждой категории. Если первые три категории : Бюджет, Расширенный отдых, Роскошь, и Бюджет имеет 5 хитов, Extended-Stay имеет 6, и Роскошь имеет 4, то аспекты упорядочены как расширенный пребывания, бюджет, роскошь. Еще одним примером является"facet=Rating,sort:-value". Он создает аспекты для всех возможных рейтингов, в порядке убывания по значению. Если рейтинги от 1 до 5, аспекты упорядочены 5, 4, 3, 2, 1, независимо от того, сколько документов соответствует каждому рейтингу.
values Предоставляет значения для меток аспектов. Установите числовые значения с разделителем "канал" или значения Edm.DateTimeOffset, задающие динамический набор значений для записей аспектов. Значения должны быть перечислены в последовательном порядке возрастания, чтобы получить ожидаемые результаты. "facet=baseRate,values:10 | 20" производит три аспекта сегментов: один для базовой ставки 0 до, но не включая 10, один для 10 до, но не включая 20, и один для 20 и выше. Строка "facet=lastRenovationDate,values:2024-02-01T00:00:00Z" создает две фасетные категории: одну для отелей, отремонтированных до февраля 2024 года, и одну для отелей, отремонтированных 1 февраля 2024 года или позже.
interval Предоставляет последовательность интервалов для аспектов, которые можно сгруппировать в интервалы. Целочисленный интервал больше нуля для чисел или минут, часов, дня, недели, месяца, квартала, года для значений даты. "facet=baseRate,interval:100" создает корзины граней на основе диапазонов базовых ставок размером 100. Если базовые ставки все от $60 до $600, есть группы для 0-100, 100-200, 200-300, 300-400, 400-500 и 500-600. Строка "facet=lastRenovationDate,interval:year" производит один фасетный контейнер для каждого года отель был отремонтирован.
timeoffset Указывает смещение времени в формате UTC, которое необходимо учитывать при установке границ времени. Установите значение ([+-]hh:mm, [+-]hhmm, or [+-]hh). Если используется, timeoffset параметр должен сочетаться с параметром интервала и только при применении к полю типа Edm.DateTimeOffset. "facet=lastRenovationDate,interval:day,timeoffset:-01:00" использует границу дня, которая начинается во время 01:00:00 UTC (в полночь в целевом часовом поясе).

count и sort может сочетаться в одной спецификации аспектов, но они не могут быть объединены с interval или values.

interval и values не может объединяться вместе.

Аспекты интервала в дате вычисляются на основе времени UTC, если timeoffset не указано. Например, граница дня для "facet=lastRenovationDate,interval:day" начинается в 00:00:00 UTC.

Базовый пример аспектов

Следующие фасетные запросы применяются к образцовому индексу отелей. Вы можете использовать представление JSON в обозревателе поиска для вставки JSON-запроса. Для получения помощи при начале работы см. раздел «Добавление фасетной навигации к результатам поиска».

Первый запрос получает аспекты для категорий, рейтингов, тегов и комнат с значениями baseRate в определенных диапазонах. Обратите внимание, что последний аспект находится в подфилде коллекции Комнат. Фасеты считают родительский документ (Отели) и не промежуточные поддокументы (номера), поэтому ответ определяет количество отелей, в которых есть номера в каждой ценовой категории.

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 
}  

Во втором примере фильтр используется для сузки предыдущего результата фасетного запроса после выбора пользователем рейтинга 3 и категории "Мотель".

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  
} 

Третий пример задает верхний предел для уникальных терминов, возвращаемых в запросе. Значение по умолчанию равно 10, но это значение можно увеличить или уменьшить с помощью параметра счетчика в атрибуте аспектов. В этом примере возвращаются аспекты для города, ограниченные 5.

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

В этом примере показаны три аспекта для "Категория", "Теги" и "Рейтинг", с переопределением счетчика на "Теги" и переопределение диапазона для "Оценка", которое в противном случае сохраняется в качестве двойника в индексе.

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" уменьшите количество тегов в разделе "Теги" до пяти лучших.

Только для числовых значений и значений DateTime можно явно задать значения в поле фасета (например, facet=Rating,values:1|2|3|4|5), чтобы результаты были разделены на непрерывные диапазоны (будь то диапазоны на основе числовых значений или периодов времени). Кроме того, можно добавить "interval", как и в facet=Rating,interval:1.

Каждый диапазон создается с использованием отправной точки 0 и конечной точки, равной значению из списка. Затем из всего диапазона удаляется предыдущий диапазон, что позволяет создавать дискретные интервалы.

Пример уникальных значений

Вы можете сформулировать запрос, возвращающий отдельное число значений для каждого поля фасетной области. В этом примере формулируется пустой или неквалифицированный запрос ("search": "*"), соответствующий всем документам, но установив top в ноль, вы получаете только подсчеты без результатов.

Для краткости этот запрос содержит только два поля, помеченные как facetable в примере индекса отелей.

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, можно настроить иерархию аспектов с помощью операторов > и ;.

Оператор вложенных (иерархических) > обозначает связь родительского-дочернего элемента, а оператор ; с точкой с запятой обозначает несколько полей на одном уровне вложения, которые все являются дочерними элементами одного и того же родительского элемента. Родительский элемент должен содержать только одно поле. Должны быть как родительские поля facetable, так и дочерние.

Порядок операций в выражении аспектов, включающих иерархии аспектов:

  • оператор options (запятая ,), разделяющий параметры аспекта для поля аспектов, например запятую в Rooms/BaseRate,values
  • круглые скобки, такие как заключенные в скобки (Rooms/BaseRate,values:50 ; Rooms/Type).
  • Оператор вложения (угловая скобка >)
  • Оператор добавления (точка с запятой ;), показанный во втором примере "Tags>(Rooms/BaseRate,values:50 ; Rooms/Type)" в этом разделе, где две дочерние грани являются равноправными элементами под родительским элементом Тегов.

Существует несколько примеров для иерархий аспектов. Первый пример — это запрос, который возвращает только несколько документов, что полезно для просмотра полного ответа. Фасеты подсчитывают родительский документ (Отели), а не промежуточные поддокументы (номера), поэтому в ответе определяется количество отелей, в которых есть любые номера в каждой группе фасетов.

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 
}

Результаты этого запроса приведены следующим образом. Оба отеля имеют бассейны. Для других тегов только один отель предоставляет удобства.

{
  "@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"
      }
    }
  ]
}

Второй пример расширяет предыдущий, демонстрируя несколько аспектов верхнего уровня с несколькими дочерними элементами. Обратите внимание, что оператор с точкой с запятой (;) отделяет каждый дочерний элемент.

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

Чтобы вернуть эту иерархию, создайте запрос, в котором категории и рейтинги являются братьями и сестрами в разделе Address/City.

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

Если удалить внутренние скобки, Категория и Рейтинг больше не рассматриваются как равные, так как правила порядка означают, что > оператор обрабатывается раньше ;.

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

Родительский элемент верхнего уровня по-прежнему является адресом или StateProvince, но теперь адрес/город и рейтинг находятся на том же уровне.

Address/StateProvince
  Rating
  Address/City
    Category

Пример фильтрации аспектов

Замечание

Эта функция сейчас доступна в общедоступной предварительной версии. Этот предварительный просмотр предоставляется без соглашения об уровне обслуживания и не предназначается для производственных рабочих нагрузок. Некоторые функции могут не поддерживаться или их возможности могут быть ограничены. Для получения дополнительной информации см. Дополнительные условия использования для предварительных версий Microsoft Azure.

Начиная с 2025-03-01-preview REST API и доступного на портале Azure, можно настроить фасетные фильтры.

Фильтрация фасетов позволяет ограничить значения фасетов, возвращаемые соответствующих указанному регулярному выражению. Два новых параметра принимают регулярное выражение, которое применяется к полю аспектов:

  • includeTermFilter фильтрует значения аспектов для тех, которые соответствуют регулярному выражению
  • excludeTermFilter фильтрует значения аспектов для тех, которые не соответствуют регулярному выражению

Если строка аспектов удовлетворяет обоим условиям, excludeTermFilter имеет приоритет, так как сначала набор строк корзины оценивается с помощью includeTermFilter, а затем исключается с помощью excludeTermFilter.

Возвращаются только те значения аспектов, которые соответствуют регулярному выражению. Эти параметры можно объединить с другими параметрами аспектов (например, countи sortиерархическим аспектом) в строковых полях.

Так как регулярное выражение вложено в строковое значение JSON, необходимо избежать двойной кавычки (") и символов обратной косой черты (\). Само регулярное выражение разделено косой чертой (/). Дополнительные сведения о шаблонах escape-адресов см. в статье "Поиск регулярных выражений".

В следующем примере показано, как избежать специальных символов в регулярном выражении, таких как обратная косая черта, двойные кавычки или символы синтаксиса регулярных выражений.

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

Ниже приведен пример фильтра аспектов, который соответствует бюджету и Extended-Stay отелям, с рейтингом в качестве ребенка каждой категории отеля.

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, можно группировать категории.

Агрегаты аспектов позволяют вычислять метрики из значений аспектов. Возможность агрегирования работает вместе с существующими опциями фасетирования. Поддерживается только sum. Добавление metric: sum к числовому аспекту объединяет все значения каждого контейнера.

Можно добавить значение по умолчанию для использования, если документ содержит значение NULL для этого поля: "facets": [ "Rooms/SleepsCount, metric: sum, default:2"] Если у комнаты пустое значение для поля Rooms/SleepsCount, значение по умолчанию заменяет отсутствующее значение.

Можно суммировать любое поле аспектов числового типа данных (за исключением векторов и географических координат).

Ниже приведен пример использования индекса hotels-sample-index. Поле Rooms/SleepsCount является аспектичным и числовым, поэтому мы выбираем это поле для демонстрации суммы. Если мы суммируем это поле, мы получаем количество сна для всего отеля. Помните, что аспекты считают родительский документ (Отели) и не промежуточные поддокументы (номера), поэтому ответ суммирует SleepsCount всех номеров для всего отеля. В этом запросе мы добавим фильтр для подсчета 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
}

Ответ запроса может выглядеть следующим образом. Windy Ocean Model может разместить в общей сложности 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#: добавьте поиск в веб-приложения , например фасетную навигацию, содержащую код для слоя презентации. В этом примере также содержатся фильтры, предложения и автозавершение. Он использует JavaScript и React для слоя презентации.