Geo-ruimtelijke OData-functies in Azure AI Search - geo.distance
en geo.intersects
Azure AI Search biedt ondersteuning voor georuimtelijke query's in OData-filterexpressies via de geo.distance
en geo.intersects
functies. De geo.distance
functie retourneert de afstand in kilometers tussen twee punten, één een veld- of bereikvariabele en één een constante die wordt doorgegeven als onderdeel van het filter. De geo.intersects
functie retourneert true
als een bepaald punt zich binnen een bepaalde veelhoek bevindt, waarbij het punt een veld- of bereikvariabele is en de veelhoek wordt opgegeven als een constante die wordt doorgegeven als onderdeel van het filter.
De geo.distance
functie kan ook worden gebruikt in de parameter $orderby om zoekresultaten te sorteren op afstand van een bepaald punt. De syntaxis voor geo.distance
in $orderby is hetzelfde als in $filter. geo.distance
Wanneer u in $orderby gebruikt, moet het veld waarop het van toepassing is van het type Edm.GeographyPoint
zijn en moet het ook sorteerbaar zijn.
Notitie
geo.distance
Wanneer u in de parameter $orderby gebruikt, moet het veld dat u aan de functie doorgeeft slechts één geografisch punt bevatten. Met andere woorden, het moet van het type Edm.GeographyPoint
zijn en niet Collection(Edm.GeographyPoint)
. Het is niet mogelijk om te sorteren op verzamelingsvelden in Azure AI Search.
Syntaxis
Het volgende EBNF (Extended Backus-Naur Form) definieert de grammatica van de geo.distance
en geo.intersects
functies, evenals de geo-ruimtelijke waarden waarop ze werken:
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)*
Er is ook een interactief syntaxisdiagram beschikbaar:
Notitie
Zie naslaginformatie over de syntaxis van de OData-expressie voor Azure AI Search voor het volledige EBNF.
geo.distance
De geo.distance
functie heeft twee parameters van het type Edm.GeographyPoint
en retourneert een Edm.Double
waarde die de afstand tussen deze in kilometers is. Dit verschilt van andere services die ondersteuning bieden voor geo-ruimtelijke OData-bewerkingen, die doorgaans afstanden in meters retourneren.
Een van de parameters moet geo.distance
een geografiepuntconstante zijn en de andere moet een veldpad zijn (of een bereikvariabele in het geval van een filter dat wordt herhaald over een veld van het type Collection(Edm.GeographyPoint)
). De volgorde van deze parameters maakt niet uit.
De geografiepuntconstante is van de vorm geography'POINT(<longitude> <latitude>)'
, waarbij de lengte- en breedtegraad numerieke constanten zijn.
Notitie
geo.distance
Wanneer u een filter gebruikt, moet u de afstand die door de functie wordt geretourneerd, vergelijken met een constante met behulp van lt
, le
of gt
ge
. De operators eq
en ne
worden niet ondersteund bij het vergelijken van afstanden. Dit is bijvoorbeeld een juist gebruik van geo.distance
: $filter=geo.distance(location, geography'POINT(-122.131577 47.678581)') le 5
.
geo.intersects
De geo.intersects
functie heeft een variabele van het type Edm.GeographyPoint
en een constante Edm.GeographyPolygon
en retourneert eentrue
Edm.Boolean
-- als het punt binnen de grenzen van de veelhoek valt, false
anders.
De veelhoek is een tweedimensionaal oppervlak dat is opgeslagen als een reeks punten die een begrenzingsring definiëren (zie de onderstaande voorbeelden ). De veelhoek moet worden gesloten, wat betekent dat de eerste en laatste puntenets hetzelfde moeten zijn. Punten in een veelhoek moeten tegen de klok in volgorde staan.
Georuimtelijke query's en veelhoeken die de 180eidiaan beslaat
Voor veel georuimtelijke querybibliotheken die een query met de 180eidiaan (in de buurt van de datumlijn) bevatten, zijn off-limits of is een tijdelijke oplossing vereist, zoals het splitsen van de veelhoek in twee, één aan beide zijden van deidiaan.
In Azure AI Search werken georuimtelijke query's met een lengtegraad van 180 graden zoals verwacht als de queryshape rechthoekig is en uw coördinaten zijn uitgelijnd op een rasterindeling langs lengte- en breedtegraad (bijvoorbeeld geo.intersects(location, geography'POLYGON((179 65, 179 66, -179 66, -179 65, 179 65))'
). Anders kunt u voor niet-rechthoekige of niet-uitgelijnde vormen de benadering van gesplitste veelhoek overwegen.
Geo-ruimtelijke functies en null
Net als alle andere niet-verzamelingsvelden in Azure AI Search kunnen velden van het type Edm.GeographyPoint
waarden bevatten null
. Wanneer Azure AI Search evalueert geo.intersects
op een veld dat dat wil null
, is false
het resultaat altijd. Het gedrag van in dit geval is afhankelijk van geo.distance
de context:
- In filters,
geo.distance
van eennull
veld resulteert innull
. Dit betekent dat het document niet overeenkomt omdatnull
in vergelijking met een niet-null-waarde wordt geëvalueerd.false
- Wanneer u resultaten sorteert met behulp van $orderby,
geo.distance
resulteert eennull
veld in de maximaal mogelijke afstand. Documenten met een dergelijk veld worden lager gesorteerd dan alle andere wanneer de sorteerrichting wordt gebruikt (de standaardinstellingasc
) en hoger dan alle andere wanneer de richting isdesc
.
Voorbeelden
Filtervoorbeelden
Zoek alle hotels binnen 10 kilometer van een bepaald referentiepunt (waar locatie een veld van het type Edm.GeographyPoint
is):
geo.distance(location, geography'POINT(-122.131577 47.678581)') le 10
Zoek alle hotels in een bepaalde viewport die wordt beschreven als een veelhoek (waar locatie een veld van het type Edm.GeographyPoint
is). Houd er rekening mee dat de veelhoek gesloten is (de eerste en laatste puntenets moeten hetzelfde zijn) en dat de punten in de volgorde linksom moeten worden vermeld.
geo.intersects(location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')
Order-by-voorbeelden
Sorteer hotels aflopend rating
op en vervolgens oplopend op afstand van de opgegeven coördinaten:
rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc
Sorteer hotels in aflopende volgorde search.score
op en rating
en vervolgens in oplopende volgorde op afstand van de opgegeven coördinaten, zodat tussen twee hotels met identieke classificaties eerst de dichtstbijzijnde wordt vermeld:
search.score() desc,rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc