Funkcje geoprzestrzewne OData w usłudze Azure AI Search — geo.distance i geo.intersects

Usługa Azure AI Search obsługuje zapytania geoprzestrzewne w wyrażeniach filtrów OData za pośrednictwem geo.distance funkcji i geo.intersects . Funkcja zwraca odległość między dwoma geo.distance punktami, jedną będącą polem lub zmienną zakresu, a stałą przekazywaną jako część filtru. Funkcja geo.intersects zwraca true , jeśli dany punkt znajduje się w danym wielokącie, gdzie punkt jest polem lub zmienną zakresu, a wielokąt jest określony jako stała przekazywana jako część filtru.

Funkcja geo.distance może być również używana w parametrze $orderby do sortowania wyników wyszukiwania według odległości od danego punktu. Składnia w geo.distance$orderby jest taka sama jak w $filter. W przypadku użycia geo.distance w $orderby pole, do którego ma zastosowanie, musi być typu Edm.GeographyPoint i musi być również sortowalne.

Uwaga

W przypadku użycia geo.distance w parametrze $orderby pole przekazywane do funkcji musi zawierać tylko jeden punkt geograficzny. Innymi słowy, musi być typu Edm.GeographyPoint , a nie Collection(Edm.GeographyPoint). Nie można sortować pól kolekcji w usłudze Azure AI Search.

Składnia

Następujący formularz EBNF (rozszerzony formularz Backus-Naur) definiuje gramatykę geo.distance funkcji i geo.intersects , a także wartości geoprzestrzennych, na których działają:

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)*

Dostępny jest również interakcyjny diagram składni:

Uwaga

Zobacz dokumentację składni wyrażeń OData dla usługi Azure AI Search , aby zapoznać się z pełną pełną NF.

geo.distance

Funkcja geo.distance przyjmuje dwa parametry typu Edm.GeographyPoint i zwraca Edm.Double wartość, która jest odległością między nimi w kilometrach. Różni się to od innych usług, które obsługują operacje geoprzestrzewne OData, które zwykle zwracają odległości w metrach.

Jeden z parametrów geo.distance musi być stałą punktu geograficznego, a drugi musi być ścieżką pola (lub zmienną zakresu w przypadku iteracji filtru dla pola typu Collection(Edm.GeographyPoint)). Kolejność tych parametrów nie ma znaczenia.

Stała punktu geograficznego ma postać geography'POINT(<longitude> <latitude>)', gdzie długość geograficzna i szerokość geograficzna są stałymi liczbowymi.

Uwaga

W przypadku użycia geo.distance w filtrze należy porównać odległość zwracaną przez funkcję ze stałą przy użyciu ltwartości , , gtlelub ge. Operatory eq i ne nie są obsługiwane podczas porównywania odległości. Na przykład jest to poprawne użycie elementu geo.distance: $filter=geo.distance(location, geography'POINT(-122.131577 47.678581)') le 5.

geo.intersects

Funkcja geo.intersects przyjmuje zmienną typu Edm.GeographyPoint i stałą i zwracatrueEdm.Boolean -- wartość, jeśli punkt znajduje się w granicach wielokątaEdm.GeographyPolygon, false w przeciwnym razie.

Wielokąt jest dwuwymiarową powierzchnią przechowywaną jako sekwencja punktów definiujących pierścień ograniczenia (zobacz poniższe przykłady ). Wielokąt musi być zamknięty, co oznacza, że pierwsze i ostatnie zestawy punktów muszą być takie same. Punkty w wielokącie muszą być w kolejności odwrotnej.

Zapytania geoprzestrzewne i wielokąty obejmujące 180.

W przypadku wielu bibliotek zapytań geoprzestrzennych formułowanie zapytania zawierającego 180-ty południk (w pobliżu linii daty) jest poza limitami lub wymaga obejścia, takiego jak podzielenie wielokąta na dwa, jedno po obu stronach południa.

W usłudze Azure AI Search zapytania geoprzestrzenne zawierające długość geograficzną 180 stopni będą działać zgodnie z oczekiwaniami, jeśli kształt zapytania jest prostokątny, a współrzędne są wyrównane do układu siatki wzdłuż długości i szerokości geograficznej (na przykład geo.intersects(location, geography'POLYGON((179 65, 179 66, -179 66, -179 65, 179 65))'). W przeciwnym razie w przypadku kształtów nie prostokątnych lub nieprzypisanych należy wziąć pod uwagę podejście podzielonego wielokąta.

Funkcje geograficzne i null

Podobnie jak wszystkie inne pola inne niż kolekcje w usłudze Azure AI Search, pola typu Edm.GeographyPoint mogą zawierać null wartości. Gdy usługa Azure AI Search oblicza geo.intersects pole, które ma nullwartość , wynik będzie zawsze mieć wartość false. Zachowanie w geo.distance tym przypadku zależy od kontekstu:

  • W filtrach geo.distancenull pole powoduje wyświetlenie nullciągu . Oznacza to, że dokument nie będzie zgodny, ponieważ null w porównaniu z dowolną wartością inną niż null jest obliczana wartość false.
  • Podczas sortowania null wyników przy użyciu $orderby pole geo.distance powoduje maksymalną możliwą odległość. Dokumenty z takim polem będą sortowane niż wszystkie inne, gdy kierunek sortowania jest używany (wartość domyślna) i wyższy niż wszystkie inne, gdy kierunek asc to desc.

Przykłady

Przykłady filtrów

Znajdź wszystkie hotele w ciągu 10 kilometrów od danego punktu odniesienia (gdzie lokalizacja jest polem typu Edm.GeographyPoint):

    geo.distance(location, geography'POINT(-122.131577 47.678581)') le 10

Znajdź wszystkie hotele w danym widoku opisanym jako wielokąt (gdzie lokalizacja jest polem typu Edm.GeographyPoint). Należy pamiętać, że wielokąt jest zamknięty (pierwszy i ostatni zestaw punktów musi być taki sam), a punkty muszą być wymienione w kolejności odwrotnej.

    geo.intersects(location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')

Przykłady według kolejności

Sortuj hotele malejące według rating, a następnie rosnąco według odległości od podanych współrzędnych:

    rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc

Sortuj hotele w kolejności malejącej według search.score i rating, a następnie w kolejności rosnącej według odległości od podanych współrzędnych, tak aby między dwoma hotelami o identycznych ocenach, najbliższy jest wymieniony jako pierwszy:

    search.score() desc,rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc

Następne kroki