Partager via


Exemples de requêtes de recherche simples dans Recherche Azure AI

Dans Recherche Azure AI, la syntaxe de requête simple appelle l’analyseur de requêtes par défaut pour une recherche en texte intégral. Cet analyseur rapide gère des scénarios courants, notamment la recherche en texte intégral, la recherche filtrée et à facettes, ainsi que la recherche de préfixe. Cet article utilise des exemples pour illustrer l’utilisation de la syntaxe simple dans une demande Rechercher des documents (API REST).

Remarque

Une autre syntaxe de requête est la syntaxe Lucene, qui prend en charge des structures de requête plus complexes, telles qu’une recherche approximative et par caractères génériques. Pour plus d’informations, consultez Exemples de syntaxe de recherche Lucene .

Index hotels-sample

Les requêtes suivantes sont basées sur l’index hotels-sample, que vous pouvez créer en suivant les instructions de Démarrage rapide : Créer un index de recherche dans le portail Azure.

Les exemples de requêtes sont formulés à l’aide de l’API REST et des requêtes POST. Vous pouvez les coller et les exécuter dans un client REST. Utilisez plutôt la vue JSON du navigateur de recherche dans le portail Azure. En vue JSON, vous pouvez coller les exemples de requête présentés dans cet article.

Les en-têtes de requête doivent comporter les valeurs suivantes :

Clé Valeur
Type de contenu application/json
api-key <your-search-service-api-key>, clé de requête ou d’administration

Les paramètres URI doivent inclure le point de terminaison de votre service de recherche avec le nom de l’index, les collections de documents, la commande de recherche et la version de l’API, comme dans l’exemple suivant :

https://{{service-name}}.search.windows.net/indexes/hotels-sample-index/docs/search?api-version=2024-07-01

Le corps de la requête doit être formé comme un JSON valide :

{
    "search": "*",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "count": true
}
  • search défini sur * est une requête non spécifiée, équivalente à la recherche null ou vide. Elle n’est pas particulièrement utile, mais c’est la recherche la plus simple que vous puissiez effectuer, et elle affiche tous les champs récupérables dans l’index, avec toutes les valeurs.

  • queryType défini sur simple est la valeur par défaut et peut être omis. Il est toutefois inclus pour renforcer le fait que les exemples de requêtes de cet article sont formulés dans la syntaxe simple.

  • select défini sur une liste de champs séparés par des virgules est utilisé pour la composition des résultats de la recherche, y compris uniquement les champs qui sont utiles pour les résultats de la recherche.

  • count renvoie le nombre de documents correspondant aux critères de recherche. Une chaîne de recherche vide comptabilise tous les documents figurant dans l’index (environ 50 pour l’index hotels-sample).

La recherche en texte intégral peut porter sur n’importe quel nombre de termes autonomes ou d’expressions entre guillemets, avec ou sans opérateurs booléens.

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
}

Une recherche par mot-clé constituée d’expressions ou de termes importants a tendance à donner de meilleurs résultats. Les champs de chaîne font l’objet d’une analyse de texte lors de l’indexation et de l’interrogation, ce qui permet de supprimer les mots non essentiels comme the, and, it. Pour voir comment une chaîne de requête est mise sous forme de jeton dans l’index, transmettez la chaîne dans un appel d’analyse de texte à l’index.

Le paramètre searchMode contrôle la précision et le rappel. Si vous voulez plus de rappel, utilisez la valeur par défaut any, qui renvoie un résultat si une partie de la chaîne de requête est mise en correspondance. Si vous privilégiez la précision, quand toutes les parties de la chaîne sont mises en correspondance, remplacez searchMode par all. Testez les deux méthodes précédentes pour voir à quel point le mode de recherche modifie le résultat.

La réponse à la requête pool spa +airport doit être similaire à l’exemple suivant.

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

Vous pouvez remarquer le score de recherche dans la réponse. Il s’agit du score de pertinence de la correspondance. Par défaut, un service de recherche renvoie les 50 premières correspondances en fonction de ce score.

Des scores uniformes de 1.0 sont obtenus en l’absence de classement, soit parce que la recherche n’était pas une recherche en texte intégral, soit parce qu’aucun critère n’a été fourni. Par exemple, pour une recherche vide (search=*), les lignes sont renvoyées dans un ordre arbitraire. Si vous incluez des critères réels, vous constaterez que les scores de recherche deviendront des valeurs significatives.

Exemple 2 : Recherche par ID

Une fois que les résultats de la recherche sont retournés, l’étape logique suivante consiste à fournir une page de détails qui comprend davantage de champs du document. Cet exemple vous indique comment retourner un document unique à l’aide d’Obtenir le document en transmettant l’ID du document.

GET /indexes/hotels-sample-index/docs/41?api-version=2024-07-01

Tous les documents ont un identificateur unique. Si vous utilisez le portail, sélectionnez l’index dans l’onglet Index, puis examinez les définitions des champs pour déterminer quel champ est la clé. Dans l’API REST, l’appel GET Index retourne la définition de l’index dans le corps de la réponse.

La réponse à la requête précédente consiste en un document dont la clé est 41. Tout champ marqué comme récupérable dans la définition de l’index peut être renvoyé dans les résultats de recherche et affiché dans votre application.

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

Exemple 3 : Filtre de texte

La syntaxe de filtre est une expression OData que vous pouvez utiliser de façon autonome ou avec search. Quand ils sont utilisés ensemble dans la même requête, filter est appliqué en premier à l’index entier, puis la recherche search est effectuée sur les résultats du filtre. Les filtres peuvent donc être utiles pour améliorer les performances des requêtes, puisqu’ils limitent le nombre de documents que devra traiter la requête de recherche.

Les filtres peuvent être définis sur n’importe quel champ marqué filterable dans la définition de l’index. Pour l’index hotels-sample, les champs filtrables comprennent les champs Category, Tags, ParkingIncluded, Rating et la plupart des champs Address.

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
}

La réponse à la requête précédente est limitée aux hôtels de la catégorie Boutique et qui comprennent les termes art ou tours. Dans ce cas, il n’y a qu’une seule correspondance.

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

Exemple 4 : Fonctions de filtre

Les expressions de filtre peuvent inclure des fonctions « search.ismatch » et « search.ismatchscoring », ce qui vous permet de créer une requête de recherche dans le filtre. Cette expression de filtre utilise un caractère générique sur gratuit pour sélectionner des équipements, y compris le Wi-Fi gratuit, le stationnement gratuit, etc.

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
  }

La réponse à la requête ci-dessus retourne 27 hôtels qui offrent des services gratuits. Notez que le score de recherche est un 1 uniforme dans les résultats. Cela s’explique par le fait que l’expression de recherche est null ou vide, ce qui donne lieu à des correspondances verbatim, mais pas à une recherche en texte intégral. Les scores de pertinence sont renvoyés uniquement lors d’une recherche en texte intégral. Si vous utilisez des filtres sans search, assurez-vous d’avoir suffisamment de champs triables pour pouvoir contrôler le classement de la recherche.

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

Exemple 5 : Filtres de plage

Le filtrage de plage est pris en charge par des expressions de filtre pour n’importe quel type de données. Les exemples suivants illustrent des plages numériques et de chaînes. Les types de données sont importants dans les filtres de plage et fonctionnent mieux lorsque les données numériques se trouvent dans des champs numériques, et les données de chaîne dans des champs de chaîne. L’utilisation de données numériques dans les champs de chaîne n’est pas adaptée aux plages, car les chaînes numériques ne sont pas comparables.

La requête suivante est une plage numérique. Dans l’index hotels-sample, le seul champ numérique filtrable est 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
}

La réponse à cette requête doit être similaire à l’exemple suivant, ajusté par souci de concision.

"@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
},
...

La requête suivante est un filtre de plage sur un champ de chaîne (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
}

La réponse à cette requête doit être similaire à l’exemple suivant, ajusté par souci de concision. Dans cet exemple, il n’est pas possible d’utiliser le champ StateProvince pour le tri, car il n’est pas marqué comme triable dans la définition de l’index.

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

L’index hotels-sample inclut un champ Location (emplacement) avec des coordonnées de latitude et de longitude. Cet exemple utilise la fonction geo.distance qui applique un filtre sur les documents situés à une distance arbitraire (en kilomètres) d’un point de départ que vous spécifiez. Vous pouvez ajuster la dernière valeur de la requête (10) pour réduire ou étendre la surface d’exposition de la requête.

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
}

La réponse à cette requête renvoie tous les hôtels situés dans un rayon de 10 kilomètres des coordonnées fournies :

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

Exemple 7 : Opérateurs booléens avec searchMode

La syntaxe simple prend en charge les opérateurs booléens sous la forme de caractères (+, -, |) pour gérer la logique de requête AND, OR et NOT. La recherche booléenne se déroule comme on peut s’y attendre, à quelques exceptions près.

Dans une recherche booléenne, envisagez d’ajouter le paramètre searchMode comme mécanisme d’influence de la précision et du rappel. Les valeurs valides incluent "searchMode": "any", qui favorise le rappel (un document qui satisfait à un des critères est considéré comme une correspondance), et "searchMode": "all", qui favorise la précision (tous les critères doivent être satisfaits dans un document).

Dans une recherche booléenne, la valeur par défaut "searchMode": "any" peut prêter à confusion si vous placez plusieurs opérateurs dans une requête et obtenez des résultats moins affinés que prévu. Cela est particulièrement vrai avec l’opérateur NOT, les résultats incluant tous les documents ne contenant pas un terme ou une expression spécifique.

L'exemple suivant illustre cette situation. La requête recherche des correspondances sur restaurant qui excluent l’expression air conditioning. Si vous exécutez la requête suivante avec searchMode (any), 43 documents sont retournés : ceux qui contiennent le terme restaurant, plus tous les documents qui ne contiennent pas l’expression *air conditioning.

Notez qu’il n’y a aucune espace entre l’opérateur booléen (-) et l’expression climatisation. Les guillemets sont des guillemets d’échappement (\").

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
}

Changer pour "searchMode": "all" applique un effet cumulé aux critères et retourne un jeu de résultats plus petit (sept correspondances) constitué de documents contenant le terme restaurant, sans ceux contenant l’expression climatisation.

La réponse à cette requête est désormais similaire à l’exemple suivant, ajusté par souci de concision.

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

Exemple 8: Résultats de pagination

Grâce aux exemples précédents, vous avez découvert les paramètres qui ont une incidence sur la composition des résultats de recherche, notamment le paramètre select, qui détermine quels champs se trouvent dans un résultat, les ordres de tri et comment inclure le nombre de correspondances. Cet exemple est la suite de la composition des résultats de la recherche sous la forme de paramètres de pagination qui vous permettent de traiter par lot le nombre de résultats qui s’affichent dans une page donnée.

Par défaut, un service de recherche renvoie les 50 premières correspondances. Pour contrôler le nombre de correspondances de chaque page, utilisez le paramètre top pour définir la taille du lot, puis skip pour récupérer les lots suivants.

L’exemple suivant utilise un filtre et un ordre de tri sur le champ Rating (filtrable et triable), car il est plus facile de voir les effets de la pagination sur les résultats triés. Lors d’une requête de recherche complète normale, les principales correspondances sont classées et paginées par @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
}

La requête trouve 21 documents correspondants, mais comme vous avez spécifié top, la réponse retourne seulement les cinq premières correspondances, avec des scores allant de 4,9 à 4,7 avec Lakeside B & B.

Pour obtenir les cinq suivants, ignorez le premier lot :

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
}

La réponse du deuxième lot ignore les cinq premières correspondances, et renvoie les cinq suivantes, en commençant par Pull’r Inn Motel. Pour continuer avec davantage de lots, conservez top sur cinq, puis incrémentez skip de cinq à chaque nouvelle demande (skip=5, skip=10, skip=15, etc.).

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

Maintenant que vous en savez un peu plus sur la syntaxe de base des requêtes, vous pouvez essayer de spécifier les requêtes dans le code. Le lien suivant explique comment configurer des requêtes de recherche à l’aide des kits de développement logiciel (SDK) Azure.

Vous trouverez davantage d’informations de référence sur la syntaxe et sur l’architecture de requête ainsi que des exemples en cliquant sur les liens suivants :