Delen via


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:

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, leof gtge. 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 eentrueEdm.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 falsehet resultaat altijd. Het gedrag van in dit geval is afhankelijk van geo.distance de context:

  • In filters, geo.distance van een null veld resulteert in null. Dit betekent dat het document niet overeenkomt omdat null in vergelijking met een niet-null-waarde wordt geëvalueerd.false
  • Wanneer u resultaten sorteert met behulp van $orderby, geo.distance resulteert een null veld in de maximaal mogelijke afstand. Documenten met een dergelijk veld worden lager gesorteerd dan alle andere wanneer de sorteerrichting wordt gebruikt (de standaardinstelling asc ) en hoger dan alle andere wanneer de richting is desc.

Voorbeelden

Filtervoorbeelden

Zoek alle hotels binnen 10 kilometer van een bepaald referentiepunt (waar locatie een veld van het type Edm.GeographyPointis):

    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.GeographyPointis). 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 ratingop 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 ratingen 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

Volgende stappen