Примеры простых поисковых запросов в поиске ИИ Azure
В службе "Поиск ИИ Azure" простой синтаксис запроса вызывает средство синтаксического анализа запросов по умолчанию для полнотекстового поиска. Средство синтаксического анализа работает быстро и обрабатывает распространенные сценарии, включая полнотекстовый поиск, фильтрованный и аспектный поиск, а также префиксный поиск. В этой статье приводятся примеры, иллюстрирующие использование простого синтаксиса в запросе Поиска документов (REST API).
Примечание.
Альтернативный синтаксис запроса — Lucene, который поддерживает более сложные структуры запросов, такие как нечеткий и подстановочный знак поиска. Дополнительные сведения см. в примерах полного синтаксиса поиска Lucene.
Образец индекса гостиниц
Следующие запросы основаны на индексе hotels-sample-index, который можно создать, следуя инструкциям в кратком руководстве. Создание индекса поиска в портал Azure.
Примеры запросов обрабатываются с помощью запросов REST API и POST. Их можно вставить и запустить в клиенте REST. Или используйте представление JSON обозревателя поиска в портал Azure. В представлении JSON можно вставить примеры запросов, показанные здесь в этой статье.
Заголовки запросов должны иметь следующие значения:
Ключ | Значение |
---|---|
Тип контента | application/json |
api-key | <your-search-service-api-key> , либо запрос, либо ключ администратора |
Параметры URI должны включать конечную точку службы поиска с именем индекса, коллекциями документов, командой поиска и версией API, как показано в следующем примере:
https://{{service-name}}.search.windows.net/indexes/hotels-sample-index/docs/search?api-version=2024-07-01
Текст запроса должен быть сформирован как допустимый JSON:
{
"search": "*",
"queryType": "simple",
"select": "HotelId, HotelName, Category, Tags, Description",
"count": true
}
search
Задано значение * — это неопределенный запрос, эквивалентный значению NULL или пустому поиску. Это не особенно полезно, но это самый простой поиск, который можно сделать, и он отображает все извлекаемые поля в индексе со всеми значениями.queryType
Для простого значения задано значение по умолчанию и может быть опущено, но он включен, чтобы подчеркнуть, что примеры запросов в этой статье выражены в простом синтаксисе.select
Для композиции результатов поиска используется список полей с разделителями-запятыми, включая только те поля, которые полезны в контексте результатов поиска.count
возвращает количество документов, соответствующих критериям поиска. В пустой строке поиска число всех документов в индексе (50 в индексе hotels-sample-index).
Пример 1. Полнотекстовый поиск
Полнотекстовый поиск может быть любым количеством автономных терминов или фраз, заключенных в кавычки, с логическими операторами или без нее.
POST /indexes/hotel-samples-index/docs/search?api-version=2024-07-01
{
"search": "pool spa +airport",
"searchMode": "any",
"queryType": "simple",
"select": "HotelId, HotelName, Category, Description",
"count": true
}
Обычно лучше всего работает поиск по ключевым словам, который состоит из важных терминов или фраз. Строковые поля проходят анализ текста во время индексирования и запроса, удаляя невостные слова, такие как и, в противном случае. Чтобы увидеть, как строка запроса помечается в индексе, передайте строку в вызове индекса Анализ текста.
Параметр searchMode
управляет точностью и отзывом. Если требуется больше отзывов, используйте любое значение по умолчанию, которое возвращает результат, если совпадает любая часть строки запроса. Если вы предпочитаете точность, где все части строки должны быть сопоставлены, измените searchMode
все. Попробуйте выполнить предыдущий запрос обоими способами, чтобы узнать, как searchMode изменяет результат.
Ответ на запрос spa и аэропорта пула должен выглядеть примерно так, как показано в следующем примере.
"@odata.count": 4,
"value": [
{
"@search.score": 6.090657,
"HotelId": "12",
"HotelName": "Winter Panorama Resort",
"Description": "Plenty of great skiing, outdoor ice skating, sleigh rides, tubing and snow biking. Yoga, group exercise classes and outdoor hockey are available year-round, plus numerous options for shopping as well as great spa services. Newly-renovated with large rooms, free 24-hr airport shuttle & a new restaurant. Rooms/suites offer mini-fridges & 49-inch HDTVs.",
"Category": "Resort and Spa"
},
{
"@search.score": 4.314683,
"HotelId": "21",
"HotelName": "Good Business Hotel",
"Description": "1 Mile from the airport. Free WiFi, Outdoor Pool, Complimentary Airport Shuttle, 6 miles from Lake Lanier & 10 miles from downtown. Our business center includes printers, a copy machine, fax, and a work area.",
"Category": "Suite"
},
{
"@search.score": 3.575948,
"HotelId": "27",
"HotelName": "Starlight Suites",
"Description": "Complimentary Airport Shuttle & WiFi. Book Now and save - Spacious All Suite Hotel, Indoor Outdoor Pool, Fitness Center, Florida Green certified, Complimentary Coffee, HDTV",
"Category": "Suite"
},
{
"@search.score": 2.6926985,
"HotelId": "25",
"HotelName": "Waterfront Scottish Inn",
"Description": "Newly Redesigned Rooms & airport shuttle. Minutes from the airport, enjoy lakeside amenities, a resort-style pool & stylish new guestrooms with Internet TVs.",
"Category": "Suite"
}
]
Обратите внимание на оценку поиска в ответе. Это оценка релевантности совпадения. По умолчанию служба поиска возвращает первые 50 совпадений на основе этой оценки.
Единообразные оценки 1.0 происходят, когда нет рангов, либо из-за того, что поиск не был полным текстом, либо из-за отсутствия условий. Например, при пустом поиске (search=*
) строки возвращаются в произвольном порядке. Если включить фактические критерии, вы увидите, что оценки поиска развиваются в значимые значения.
Пример 2. Поиск по идентификатору
После возврата результатов поиска логический следующий шаг — предоставить страницу сведений, содержащую дополнительные поля из документа. В этом примере показано, как вернуть один документ с помощью Get Document , передав идентификатор документа.
GET /indexes/hotels-sample-index/docs/41?api-version=2024-07-01
Все документы имеют уникальный идентификатор. Если вы используете портал, выберите индекс на вкладке "Индексы ", а затем просмотрите определения полей, чтобы определить, какое поле является ключом. В REST API вызов GET Index возвращает определение индекса в тексте ответа.
Ответ на предыдущий запрос состоит из документа, ключ которого равен 41. Любое поле, помеченное как извлекаемое в определении индекса, может быть возвращено в результатах поиска и отображено в приложении.
{
"HotelId": "41",
"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.",
"Description_fr": "Cet hôtel en bord de mer donnant sur la plage propose des chambres dotées d'un balcon privé et de 2 piscines intérieure et extérieure. Inspiré par la beauté naturelle de l'île, chaque chambre comprend une peinture originale de scènes locales par le propriétaire. Les chambres comprennent un mini-réfrigérateur, une cafetière Keurig et une télévision à écran plat. Divers magasins et divertissements artistiques se trouvent sur la promenade, à quelques pas.",
"Category": "Suite",
"Tags": [
"pool",
"air conditioning",
"bar"
],
"ParkingIncluded": true,
"LastRenovationDate": "2021-05-10T00:00:00Z",
"Rating": 3.5,
"Location": {
"type": "Point",
"coordinates": [
-157.846817,
21.295841
],
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
}
},
"Address": {
"StreetAddress": "1450 Ala Moana Blvd 2238 Ala Moana Ctr",
"City": "Honolulu",
"StateProvince": "HI",
"PostalCode": "96814",
"Country": "USA"
}
}
Пример 3. Фильтрация по тексту
Синтаксис фильтра — это выражение OData, которое можно использовать самостоятельно или с search
. При совместном использовании в одном запросе filter
сначала применяется ко всему индексу, а затем search
выполняется по результатам фильтра. Поэтому фильтры могут повысить производительность запросов, так как они уменьшают количество документов, которые поисковый запрос должен обработать.
Фильтры можно определить в любом поле, помеченном как filterable
в определении индекса. Для отелей-sample-index поля, доступные для фильтрации, включают категории, теги, парковкуIncluded, рейтинг и большинство полей адресов.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "art tours",
"queryType": "simple",
"filter": "Category eq 'Boutique'",
"searchFields": "HotelName,Description,Category",
"select": "HotelId,HotelName,Description,Category",
"count": true
}
Ответ на предыдущий запрос ограничен только теми отелями, которые классифицируются как Бутик, и включают термины искусства или экскурсии. В этом случае есть только одно совпадение.
"value": [
{
"@search.score": 1.2814453,
"HotelId": "2",
"HotelName": "Old Century Hotel",
"Description": "The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts. The hotel also regularly hosts events like wine tastings, beer dinners, and live music.",
"Category": "Boutique"
}
]
Пример 4. Функции фильтров
Выражения фильтра могут включать функции search.ismatch и search.ismatchscoring, что позволяет создавать поисковый запрос в фильтре. В этом выражении для фильтра используется подстановочный знак в поле бесплатный, чтобы выбрать услуги, включая бесплатный Wi-Fi, бесплатную парковку и т. д.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "",
"filter": "search.ismatch('free*', 'Tags', 'full', 'any')",
"select": "HotelName, Tags, Description",
"count": true
}
Ответ на предыдущий запрос соответствует 27 отелям, которые предлагают бесплатные удобства. Обратите внимание, что оценка поиска является единой 1 в результатах. Это обусловлено тем, что выражение поиска имеет нулевое значение или является пустым, что приводит к совпадению точных фильтров, но не вызывает полнотекстовый поиск. Оценки релевантности возвращаются только при полнотекстовом поиске. Если вы используете фильтры без search
, убедитесь, что у вас есть достаточно сортируемых полей, чтобы вы могли управлять рангом поиска.
"@odata.count": 27,
"value": [
{
"@search.score": 1,
"HotelName": "Country Residence Hotel",
"Description": "All of the suites feature full-sized kitchens stocked with cookware, separate living and sleeping areas and sofa beds. Some of the larger rooms have fireplaces and patios or balconies. Experience real country hospitality in the heart of bustling Nashville. The most vibrant music scene in the world is just outside your front door.",
"Tags": [
"laundry service",
"restaurant",
"free parking"
]
},
{
"@search.score": 1,
"HotelName": "Downtown Mix Hotel",
"Description": "Mix and mingle in the heart of the city. Shop and dine, mix and mingle in the heart of downtown, where fab lake views unite with a cheeky design.",
"Tags": [
"air conditioning",
"laundry service",
"free wifi"
]
},
{
"@search.score": 1,
"HotelName": "Starlight Suites",
"Description": "Complimentary Airport Shuttle & WiFi. Book Now and save - Spacious All Suite Hotel, Indoor Outdoor Pool, Fitness Center, Florida Green certified, Complimentary Coffee, HDTV",
"Tags": [
"pool",
"coffee in lobby",
"free wifi"
]
},
. . .
Пример 5. Фильтры диапазонов
Фильтрация диапазона поддерживается с помощью выражения фильтра для любого типа данных. В следующих примерах показаны числовые и строковые диапазоны. Типы данных важны в фильтрах диапазона и лучше всего работают, когда числовые данные находятся в числовых полях, а строковые данные — в строковых. Числовые данные в строковых полях не подходят для диапазонов, так как числовые строки не сопоставимы.
Следующий запрос является числовым диапазоном. В hotels-sample-index единственным числовым полем является фильтруемое поле Rating
.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Rating ge 2 and Rating lt 4",
"select": "HotelId, HotelName, Rating",
"orderby": "Rating desc",
"count": true
}
Ответ для этого запроса должен выглядеть примерно так, как показано в следующем примере, обрезанный для краткости.
"@odata.count": 27,
"value": [
{
"@search.score": 1,
"HotelId": "22",
"HotelName": "Lion's Den Inn",
"Rating": 3.9
},
{
"@search.score": 1,
"HotelId": "25",
"HotelName": "Waterfront Scottish Inn",
"Rating": 3.8
},
{
"@search.score": 1,
"HotelId": "2",
"HotelName": "Old Century Hotel",
"Rating": 3.6
},
...
Следующий запрос является фильтром диапазона для строкового поля (Address/StateProvince):
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Address/StateProvince ge 'A*' and Address/StateProvince lt 'D*'",
"select": "HotelId, HotelName, Address/StateProvince",
"count": true
}
Ответ для этого запроса должен выглядеть примерно так, как показано в следующем примере, обрезанный для краткости. В этом примере невозможно сортировать StateProvince
по причине того, что поле не является сортируемым в определении индекса.
{
"@odata.count": 9,
"value": [
{
"@search.score": 1,
"HotelId": "39",
"HotelName": "White Mountain Lodge & Suites",
"Address": {
"StateProvince": "CO"
}
},
{
"@search.score": 1,
"HotelId": "9",
"HotelName": "Smile Up Hotel",
"Address": {
"StateProvince": "CA "
}
},
{
"@search.score": 1,
"HotelId": "7",
"HotelName": "Roach Motel",
"Address": {
"StateProvince": "CA "
}
},
{
"@search.score": 1,
"HotelId": "34",
"HotelName": "Lakefront Captain Inn",
"Address": {
"StateProvince": "CT"
}
},
{
"@search.score": 1,
"HotelId": "37",
"HotelName": "Campus Commander Hotel",
"Address": {
"StateProvince": "CA "
}
},
. . .
Пример 6. Геопространственный поиск
Индекс hotels-sample-index включает поле Location с координатами широты и долготы. В этом примере используется функция geo.distance, которая фильтрует документы в пределах окружности начальной точки до произвольного расстояния (в километрах), которое вы предоставляете. Можно изменить последнее значение в запросе (10), чтобы уменьшить или увеличить контактную зону запроса.
POST /indexes/v/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "geo.distance(Location, geography'POINT(-122.335114 47.612839)') le 10",
"select": "HotelId, HotelName, Address/City, Address/StateProvince",
"count": true
}
Ответ на этот запрос возвращает все отели в пределах 10-километрового расстояния от указанных координат:
{
"@odata.count": 3,
"value": [
{
"@search.score": 1,
"HotelId": "45",
"HotelName": "Happy Lake Resort & Restaurant",
"Address": {
"City": "Seattle",
"StateProvince": "WA"
}
},
{
"@search.score": 1,
"HotelId": "24",
"HotelName": "Uptown Chic Hotel",
"Address": {
"City": "Seattle",
"StateProvince": "WA"
}
},
{
"@search.score": 1,
"HotelId": "16",
"HotelName": "Double Sanctuary Resort",
"Address": {
"City": "Seattle",
"StateProvince": "WA"
}
}
]
}
Пример 7. Логические операторы с параметром searchMode
Простой синтаксис поддерживает логические операторы в виде символов (+, -, |
) для поддержки логики ЗАПРОСОВ AND, OR и NOT. Логический поиск работает привычным образом, кроме нескольких исключений, заслуживающих внимания.
В логическом поиске рассмотрите возможность добавления searchMode
параметра в качестве механизма влияния на точность и отзыв. Допустимые значения включают "searchMode": "any"
отзыв (документ, удовлетворяющий любому из критериев, считается совпадением), и "searchMode": "all"
пользу точности (все критерии должны соответствовать в документе).
В контексте логического поиска значение по умолчанию "searchMode": "any"
может быть запутано, если вы стекаете запрос с несколькими операторами и получаете более широкие результаты вместо более узких результатов. Это особенно верно с NOT, где результаты включают все документы , не содержащие определенного термина или фразы.
Это показывается в следующем примере. Запрос ищет совпадения в ресторане, который исключает кондиционирование фразы. При выполнении следующего запроса с помощью searchMode (любой), возвращаются 43 документа: те, которые содержат термин ресторан, а также все документы, у которых нет фразы *кондиционирования воздуха.
Обратите внимание, что между логическим оператором (-
) и кондиционером фразы нет места. Кавычки экранируются (\"
).
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "restaurant -\"air conditioning\"",
"searchMode": "any",
"searchFields": "Tags",
"select": "HotelId, HotelName, Tags",
"count": true
}
"searchMode": "all"
Изменение применения совокупного влияния на критерии и возвращает меньший результирующий набор (семь совпадений), состоящий из документов, содержащих термин ресторан, минус те, которые содержат кондиционер фразы.
Ответ для этого запроса теперь будет выглядеть примерно так, как показано в следующем примере, обрезанный для краткости.
{
"@odata.count": 14,
"value": [
{
"@search.score": 3.1383743,
"HotelId": "18",
"HotelName": "Ocean Water Resort & Spa",
"Tags": [
"view",
"pool",
"restaurant"
]
},
{
"@search.score": 2.028083,
"HotelId": "22",
"HotelName": "Lion's Den Inn",
"Tags": [
"laundry service",
"free wifi",
"restaurant"
]
},
{
"@search.score": 2.028083,
"HotelId": "34",
"HotelName": "Lakefront Captain Inn",
"Tags": [
"restaurant",
"laundry service",
"coffee in lobby"
]
},
...
Пример 8. Постраничные результаты
В предыдущих примерах вы узнали о параметрах, влияющих на состав результатов поиска, в том числе select
о том, какие поля находятся в результатах, заказах сортировки и о том, как включить количество всех совпадений. Этот пример является продолжением объединения результатов поиска в виде параметров постраничного вывода, которые позволяют задавать количество результатов, отображаемых на одной странице.
По умолчанию служба поиска возвращает первые 50 соответствий. Чтобы контролировать количество совпадений на каждой странице, используйте top
для определения размера пакета, а затем для skip
получения последующих пакетов.
В следующем примере используется фильтр и порядок сортировки в Rating
поле (рейтинг можно отфильтровать и сортировать), так как проще увидеть эффекты разбиения по страницам в отсортированных результатах. В обычном полном поисковом запросе верхние совпадения ранжируются и выстраиваются по страницам @search.score
.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Rating gt 4",
"select": "HotelName, Rating",
"orderby": "Rating desc",
"top": 5,
"count": true
}
Запрос находит 21 совпадающих документов, но так как вы указали top
, ответ возвращает только первые пять совпадений, с рейтингами, начиная с 4,9, и заканчивается на 4,7 с Lakeside B и B.
Чтобы получить следующую пятерку, пропустите первый пакет:
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Rating gt 4",
"select": "HotelName, Rating",
"orderby": "Rating desc",
"top": 5,
"skip": 5,
"count": true
}
Ответ на второй пакет пропускает первые пять матчей, возвращая следующие пять, начиная с Pull'r Inn Motel. Чтобы продолжить работу с дополнительными пакетами, вы будете держать top
на пять, а затем увеличить skip
на пять по каждому новому запросу (skip=5, skip=10, skip=15 и т. д.).
{
"@odata.count": 21,
"value": [
{
"@search.score": 1,
"HotelName": "Head Wind Resort",
"Rating": 4.7
},
{
"@search.score": 1,
"HotelName": "Sublime Palace Hotel",
"Rating": 4.6
},
{
"@search.score": 1,
"HotelName": "City Skyline Antiquity Hotel",
"Rating": 4.5
},
{
"@search.score": 1,
"HotelName": "Nordick's Valley Motel",
"Rating": 4.5
},
{
"@search.score": 1,
"HotelName": "Winter Panorama Resort",
"Rating": 4.5
}
]
}
Связанный контент
Теперь, когда у вас есть опыт использования базового синтаксиса запросов, попробуйте задавать запросы в коде. В следующей ссылке описывается настройка поисковых запросов с помощью пакетов SDK Azure.
Дополнительные справочные материалы по синтаксису, архитектуре запросов и примерам см. в следующих ссылках: