Fonctions géospatiales OData dans Azure AI Search - geo.distance
et geo.intersects
Azure AI Search prend en charge les requêtes géospatiales dans les expressions de filtre OData via les fonctions geo.distance
et geo.intersects
. La fonction geo.distance
renvoie la distance en kilomètres entre deux points, l’un étant un champ ou une variable de portée et l’autre une constante passée comme partie du filtre. La fonction geo.intersects
renvoie true
si un point donné se trouve dans un polygone donné, où le point est un champ ou une variable de portée et où le polygone est spécifié sous la forme d’une constante passée comme partie du filtre.
La fonction geo.distance
peut également être utilisée dans le paramètre $orderby pour trier les résultats de recherche par distance à partir d’un point donné. La syntaxe pour geo.distance
dans $orderby est la même que dans $filter. Lors de l’utilisation de geo.distance
dans $orderby, le champ auquel elle s’applique doit être de type Edm.GeographyPoint
et être aussi triable.
Remarque
Si vous spécifiez geo.distance
dans le paramètre $orderby, le champ que vous passez à la fonction doit contenir un seul point géographique. Autrement dit, il doit être de type Edm.GeographyPoint
et pas de type Collection(Edm.GeographyPoint)
. Le tri sur les champs de collection n’est pas possible dans Azure AI Search.
Syntaxe
L’extension EBNF suivante (Extended Backus-Naur Form) définit la grammaire des fonctions geo.distance
et geo.intersects
, ainsi que les valeurs géospatiales sur lequel elles fonctionnent :
geo_distance_call ::=
'geo.distance(' variable ',' geo_point ')'
| 'geo.distance(' geo_point ',' variable ')'
geo_point ::= "geography'POINT(" lon_lat ")'"
lon_lat ::= float_literal ' ' float_literal
geo_intersects_call ::=
'geo.intersects(' variable ',' geo_polygon ')'
/* You need at least four points to form a polygon, where the first and
last points are the same. */
geo_polygon ::=
"geography'POLYGON((" lon_lat ',' lon_lat ',' lon_lat ',' lon_lat_list "))'"
lon_lat_list ::= lon_lat(',' lon_lat)*
Un diagramme de syntaxe interactif est également disponible :
Remarque
Consultez Informations de référence sur la syntaxe d’expression OData pour Azure AI Search pour l’extension EBNF complète.
geo.distance
La fonction geo.distance
prend deux paramètres de type Edm.GeographyPoint
et renvoie une valeur Edm.Double
qui correspond à la distance entre eux en kilomètres. Ceci diffère des autres services qui prennent en charge des opérations géospatiales OData, qui renvoient généralement les distances en mètres.
L’un des paramètres de geo.distance
doit être une constante de point géographique et l’autre un chemin d’accès à un champ (ou une variable de portée dans le cas d’un filtre effectuant une itération sur un champ de type Collection(Edm.GeographyPoint)
). Peu importe l’ordre de ces paramètres.
La constante de point géographique est au format geography'POINT(<longitude> <latitude>)'
, où la longitude et latitude sont des constantes numériques.
Remarque
Quand vous utilisez ge
dans un filtre, vous devez comparer la distance renvoyée par la fonction avec une constante en utilisant geo.distance
, lt
, le
ou gt
. Les opérateurs eq
et ne
ne sont pas pris en charge lors de la comparaison de distances. Voici par exemple une utilisation correcte de geo.distance
: $filter=geo.distance(location, geography'POINT(-122.131577 47.678581)') le 5
.
geo.intersects
La fonction geo.intersects
prend une variable de type Edm.GeographyPoint
et une constante Edm.GeographyPolygon
et renvoie un Edm.Boolean
-- true
si le point se trouve dans les limites du polygone, false
dans le cas contraire.
Le polygone est une surface en deux dimensions stockée sous la forme d’une séquence de points définissant un cadre englobant (voir les exemples ci-dessous). Le polygone doit être fermé, ce qui signifie que le premier point et le dernier doivent être le même. Les points d’un polygone doivent être dans le sens antihoraire.
Requêtes géospatiales et polygones couvrant le 180e méridien
Pour de nombreuses bibliothèques de requêtes géospatiales, la formulation d’une requête incluant le 180e méridien (près de la ligne de changement de date) est hors limites ou nécessite une solution de contournement, comme diviser le polygone en deux parties, une de chaque côté du méridien.
Dans Azure AI Search, les requêtes géospatiales incluant une longitude de 180 degrés fonctionnent normalement si la forme de la requête est rectangulaire et que vos coordonnées s’alignent sur une disposition en grille le long de la longitude et de la latitude (par exemple geo.intersects(location, geography'POLYGON((179 65, 179 66, -179 66, -179 65, 179 65))'
). Sinon, pour les formes non rectangulaires ou non alignées, envisagez l’approche par division du polygone.
Fonctions géospatiales et null
Comme tous les autres champs qui ne sont pas des collections dans Azure AI Search, les champs de type Edm.GeographyPoint
peuvent contenir des valeurs null
. Lorsque Azure AI Search évalue geo.intersects
pour un champ qui est null
, le résultat sera toujours false
. Le comportement de geo.distance
dans ce cas dépend du contexte :
- Dans les filtres, la valeur
geo.distance
d’un champnull
donne le résultatnull
. Cela signifie que le document ne correspond pas, carnull
comparé à n’importe quelle valeur non null a pour résultatfalse
. - Lors du tri des résultats à l’aide de $orderby, la valeur
geo.distance
d’un champnull
donne pour résultat la distance maximale possible. Les documents comportant un tel champ auront un niveau de tri inférieur par rapport aux autres lorsque le sens de triasc
est utilisé (par défaut) et supérieur à tous les autres utilisateurs lorsque le sens estdesc
.
Exemples
Exemples de filtres
Rechercher tous les hôtels dans les 10 kilomètres d’un point de référence donnée (où l’emplacement est un champ de type Edm.GeographyPoint
) :
geo.distance(location, geography'POINT(-122.131577 47.678581)') le 10
Rechercher tous les hôtels dans une fenêtre d’affichage décrite sous forme de polygone (où l’emplacement est un champ de type Edm.GeographyPoint
). Notez que le polygone est fermé (les définitions du premier et du dernier point doivent les mêmes) et les points doivent être listés dans le sens antihoraire.
geo.intersects(location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')
Exemples de clause Order by
Trier les hôtels par ordre décroissant sur rating
, puis par ordre croissant sur la distance à partir des coordonnées spécifiées :
rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc
Trier les hôtels par ordre décroissant sur search.score
et rating
, puis par ordre croissant sur la distance à partir des coordonnées spécifiées, de sorte qu’entre deux d’hôtels avec une évaluation identique, le plus proche soit listé en premier :
search.score() desc,rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc