Syntaxe de requête simple dans Recherche Azure AI

Pour les scénarios de recherche en texte intégral, Azure AI Search implémente deux langages de requête basés sur Lucene, chacun aligné sur un analyseur de requêtes. L'analyseur de requêtes simples est la valeur par défaut. Il couvre les cas d'utilisation courants et tente d'interpréter une requête même si elle n'est pas parfaitement composée. L'autre analyseur est Lucene Query Parser et prend en charge des constructions de requêtes plus avancées.

Cet article est la référence sur la syntaxe de requête pour l’analyseur de requête simple.

La syntaxe de requête pour les deux analyseurs s'applique aux expressions de requête passées en paramètre search d'une requête de requête, à ne pas confondre avec la syntaxe OData, avec sa propre syntaxe et ses propres règles pour les expressions filter et orderby dans la même requête.

Bien que l’analyseur simple soit basé sur la classe de l’analyseur de requête simple Apache Lucene, son implémentation dans Recherche Azure AI exclut la recherche approximative. Si vous avez besoin de la recherche approximative, utilisez plutôt la syntaxe de requête Lucene complète.

Exemple (syntaxe simple)

Cet exemple montre une requête simple, distinguée par "queryType": "simple" et une syntaxe valide. Bien que le type de requête soit défini ci-dessous, il s’agit du type par défaut et il peut être omis, sauf si vous effectuez une restauration à partir d’un autre type. L’exemple suivant est une recherche sur des termes indépendants, avec une exigence stipulant que tous les documents correspondants incluent « pool ».

POST https://{{service-name}}.search.windows.net/indexes/hotel-rooms-sample/docs/search?api-version=2020-06-30
{
  "queryType": "simple",
  "search": "budget hotel +pool",
  "searchMode": "all"
}

Le paramètre searchMode est approprié dans cet exemple. Chaque fois que les opérateurs booléens se trouvent sur la requête, vous devez généralement définir searchMode=all pour vous assurer que toutes les des critères sont mises en correspondance. Dans le cas contraire, vous pouvez utiliser searchMode=any (par défaut) qui préfère le rappel à la précision.

Pour obtenir d’autres exemples, consultez Exemples de syntaxe de requête simple. Pour plus d’informations sur les paramètres et la demande de requête, consultez Rechercher dans des documents (API REST).

Recherche par mot clé sur des termes et des expressions

Les chaînes transmises au paramètre search peuvent inclure des termes ou des expressions dans les différents langages, opérateurs booléens, opérateurs de précédence, caractères génériques ou de préfixe pour les requêtes « commence par », caractères d’échappement et caractères d’encodage d’URL pris en charge. Le paramètre search est facultatif. S’il n’est pas spécifié, la recherche (search=* ou search=" ") retourne les 50 premiers documents dans un ordre arbitraire (non classé).

  • Une recherche de termes est une requête portant sur un ou plusieurs termes et dans laquelle un des termes est considéré comme une correspondance.

  • Une recherche d’expression est une expression exacte placée entre guillemets " ". Par exemple, si Roach Motel (sans guillemets) recherche les documents contenant Roach et/ou Motel n’importe où dans n’importe quel ordre, "Roach Motel" (avec des guillemets) établit une correspondance seulement avec les documents qui contiennent cette expression entière, avec les mots dans cet ordre (l’analyse lexicale s’applique néanmoins toujours).

Selon votre client de recherche, vous devrez peut-être faire précéder les guillemets de caractères d’échappement dans une recherche d’expression. Par exemple, dans une requête POST, une recherche d’expressions sur "Roach Motel" dans le corps de la requête peut être spécifiée comme "\"Roach Motel\"". Si vous utilisez les kits de développement logiciel (SDK) Azure, le client de recherche échappe les guillemets lorsqu’il sérialise le texte de recherche. Votre expression de recherche peut être envoyée en tant que « Roach Motel ».

Par défaut, toutes les chaînes passées dans le paramètre search subissent une analyse lexicale. Assurez-vous de bien comprendre le comportement de segmentation du texte en unités lexicales de l’analyseur que vous utilisez. Souvent, lorsque les résultats de la requête sont inattendus, cela peut être dû à la façon dont les termes sont segmentés en unités lexicales au moment de la requête. Vous pouvez tester la segmentation du texte en unités lexicales sur des chaînes spécifiques pour confirmer la sortie.

Tout texte d’entrée avec un ou plusieurs termes est considéré comme un point de départ valide pour l’exécution des requêtes. Recherche Azure AI établit une correspondance avec les documents contenant tout ou partie des termes, y compris d’éventuelles variations détectées lors de l’analyse du texte.

Aussi simple que cela puisse paraître, un aspect de l’exécution des requêtes dans Recherche Azure AI est qu’elles peuvent produire des résultats inattendus, en augmentant le nombre des résultats de la recherche au lieu de les diminuer quand vous ajoutez plus de termes et d’opérateurs à la chaîne d’entrée. Si cette extension se produit réellement dépend de l’inclusion d’un opérateur NOT, combinée à un paramètre de searchMode qui détermine comment NOT est interprété en termes de comportement AND ou OR. Pour plus d’informations, consultez l’opérateur NOT sous opérateurs booléens.

Opérateurs booléens

Vous pouvez incorporer des opérateurs booléens dans une chaîne de requête pour améliorer la précision d’une correspondance. Dans la syntaxe simple, les opérateurs booléens sont basés sur des caractères. Les opérateurs de texte, comme le mot AND, ne sont pas pris en charge.

Caractère Exemple Usage
+ pool + ocean Une opération AND . Par exemple, pool + ocean stipule qu’un document doit contenir les deux termes.
| pool | ocean Une opération OR recherche une correspondance lorsque l’un ou l’autre terme est trouvé. Dans l’exemple, le moteur de requête retourne une correspondance sur les documents contenant pool ou ocean ou les deux. Étant donné que OR est l’opérateur de conjonction par défaut, vous pouvez également l’abandonner, de sorte que pool ocean est l’équivalent de pool | ocean.
- pool – ocean Une opération NOT retourne des correspondances sur les documents qui excluent le terme.

Le paramètre searchMode d’une requête contrôle si un terme avec l’opérateur NOT est ANDed ou ORed avec d’autres termes dans la requête (en supposant qu’il n’existe aucun opérateur booléen sur les autres termes). Les valeurs valides sont any ou all.

searchMode=any augmente le rappel des requêtes en incluant plus de résultats, et par défaut - est interprété comme « OR NOT ». Par exemple, pool - ocean correspond aux documents qui contiennent le terme pool ou à ceux qui ne contiennent pas le terme ocean.

searchMode=all augmente la précision des requêtes en incluant moins de résultats et, par défaut, « - » est interprété comme « AND NOT ». Par exemple, avec searchMode=any, la requête pool - ocean cherchera des documents qui contiennent le terme « pool » et qui ne contiennent pas le terme « ocean ». Il s’agit sans doute d’un comportement plus intuitif pour l’opérateur -. Ainsi, préférez searchMode=all à searchMode=any si vous souhaitez optimiser la précision des recherches plutôt que le rappel, et si vos utilisateurs utilisent fréquemment l'opérateur - dans les recherches.

Lorsque vous choisissez un paramètre searchMode, tenez compte des modèles d’interaction utilisateur pour les requêtes liées à différentes applications. Les utilisateurs qui recherchent des informations sont plus enclins à inclure un opérateur dans une requête, contrairement aux sites de commerce électronique qui disposent de structures de navigation intégrées.

Requête de préfixe

Pour les requêtes « commence par », ajoutez un opérateur de suffixe (*) en tant qu’espace réservé pour le reste d’un terme. Une requête de préfixe doit commencer par au moins un caractère alphanumérique avant que vous puissiez ajouter l’opérateur de suffixe.

Caractère Exemple Utilisation
* lingui* correspond à « linguistique » ou à « linguini » L’astérisque (*) représente un ou plusieurs caractères de longueur arbitraire, sans tenir compte de la casse.

Comme pour les filtres, une requête de préfixe recherche une correspondance exacte. Par conséquent, il n’existe aucun scoring de pertinence (tous les résultats reçoivent un score de recherche de 1.0). Sachez que les requêtes de préfixe peuvent être lentes, en particulier si l’index est volumineux et le préfixe constitué d’un petit nombre de caractères. Une autre méthodologie, telle que la segmentation du texte en unités lexicales de type edge n-gram, peut s’effectuer plus rapidement. Les termes utilisant la recherche de préfixe ne peuvent pas dépasser 1000 caractères.

La syntaxe simple ne prend en charge que la correspondance de préfixes. Pour la correspondance de suffixes ou d’infixes à la fin ou au milieu d’un terme, utilisez la syntaxe Lucene complète pour la recherche de caractères génériques.

Échappement des opérateurs de recherche

Dans la syntaxe simple, les opérateurs de recherche incluent les caractères suivants : + | " ( ) ' \

Si l’un de ces caractères fait partie d’un jeton dans l’index, échappez-le en le faisant précéder d’une barre oblique inverse (\) dans la requête. Par exemple, supposez que vous avez utilisé un analyseur personnalisé pour la création de jetons de termes entiers, et que votre index contient la chaîne « Luxury+Hotel ». Pour obtenir une correspondance exacte sur ce jeton, insérez un caractère d’échappement : search=luxury\+hotel.

Pour simplifier les choses dans les cas les plus classiques, il existe deux exceptions à cette règle où l’échappement n’est pas nécessaire :

  • L’opérateur NOT - doit être placé en échappement seulement s’il s’agit du premier caractère après un espace. Si le - apparaît au milieu (par exemple 3352CDD0-EF30-4A2E-A512-3B30AF40F3FD), aucun échappement n’est nécessaire.

  • L’opérateur de suffixe * doit être placé en échappement seulement s’il s’agit du dernier caractère avant un espace. Si le * apparaît au milieu (par exemple 4*4=16), aucun échappement n’est nécessaire.

Remarque

Par défaut, l’analyseur standard supprime et coupe les mots sur les traits d’union, les espaces, les esperluettes et autres caractères pendant l’analyse lexicale. Si vous avez besoin que les caractères spéciaux restent dans la chaîne de requête, vous aurez peut-être besoin d’un analyseur qui les conserve dans l’index. Parmi les choix possibles figurent les analyseurs de langage naturel de Microsoft, qui conservent les mots avec trait d'union, ou un analyseur personnalisé pour les modèles plus complexes. Pour plus d'informations, consultez Termes partiels, modèles et caractères spéciaux.

Encodage de caractères dangereux et réservés dans les URL

Vérifiez que tous les caractères non sécurisés et réservés sont encodés dans une URL. Par exemple, « # » est un caractère non sécurisé, car il s’agit d’un identificateur de fragment/d’ancrage au sein d’une URL. Le caractère doit être encodé en %23 s’il est utilisé dans une URL. « & » et « = » sont des exemples de caractères réservés car ils délimitent les paramètres et spécifient des valeurs dans Azure AI Search. Pour plus d’informations, consultez RFC1738 : Uniform Resource Locators (URL).

Les caractères dangereux sont " ` < > # % { } | \ ^ ~ [ ]. Les caractères réservés sont ; / ? : @ = + &.

Caractères spéciaux

Les caractères spéciaux peuvent aller des symboles monétaires comme « $ » ou « € » aux emojis. De nombreux analyseurs, notamment l’analyseur standard par défaut, vont exclure les caractères spéciaux pendant l’indexation, ce qui signifie qu’ils ne seront pas représentés dans votre index.

Si vous avez besoin d’une représentation des caractères spéciaux, vous pouvez attribuer un analyseur qui les conserve :

  • L'analyseur d'espaces considère toute séquence de caractères séparée par des espaces blancs comme des jetons (l'emoji « ❤ » serait donc considéré comme un jeton).

  • Un analyseur de langue, tel que l’analyseur Microsoft English (en.microsoft), prend la chaîne '$' ou '€' comme jeton.

À des fins de confirmation, vous pouvez tester un analyseur pour voir quels jetons sont générés pour une chaîne donnée. Comme vous pouvez vous y attendre, vous risquez de ne pas obtenir une segmentation complète du texte en unités lexicales avec un seul analyseur. Une solution de contournement consiste à créer plusieurs champs qui contiennent le même contenu, mais avec des affectations d’analyseur différentes (par exemple, description_en, description_fr, etc. pour les analyseurs de langage).

Quand vous utilisez des caractères Unicode, assurez-vous que les symboles sont correctement placés dans une séquence d’échappement dans l’URL de la requête (par exemple, pour « ❤ », utilisez la séquence d’échappement %E2%9D%A4+). Certains clients Web effectuent cette traduction automatiquement.

Précédence (regroupement)

Vous pouvez utiliser des parenthèses pour créer des sous-requêtes, en incluant des opérateurs au sein de l’instruction entre parenthèses. Par exemple, motel+(wifi|luxury) recherche les documents contenant le terme « motel », et « wifi » ou « luxury » (ou les deux).

Limites de taille des requêtes

Si votre application génère des requêtes de recherche par programmation, nous vous recommandons de la concevoir de façon à ce qu’elle ne génère pas des requêtes d’une taille illimitée.

  • Pour GET, la longueur de l’URL ne peut pas dépasser 8 Ko.

  • Pour POST (et toute autre demande), où le corps de la demande comprend search et d’autres paramètres comme filter et orderby, la taille maximale est de 16 Mo. Les limites supplémentaires sont les suivantes :

    • La longueur maximale de la clause de recherche est de 100 000 caractères.
    • Le nombre maximal de clauses dans search (expressions séparées par AND ou OR) est 1024.
    • La taille maximale des termes de recherche est de 1000 caractères pour la recherche de préfixe.
    • Il existe également une limite d’environ 32 Ko pour la taille d’un terme individuel dans une requête.

Pour plus d’informations sur les limites de requête, consultez Limites des demandes d’API.

Étapes suivantes

Si vous allez construire des requêtes par programmation, consultez Recherche en texte intégral dans Recherche Azure AI pour comprendre les étapes du traitement des requêtes et les implications de l’analyse de texte.

Vous pouvez également consulter les articles suivants pour en savoir plus sur la construction des requêtes :