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 lt
wartości , , gt
le
lub 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 zwracatrue
Edm.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 null
wartość , wynik będzie zawsze mieć wartość false
. Zachowanie w geo.distance
tym przypadku zależy od kontekstu:
- W filtrach
geo.distance
null
pole powoduje wyświetlenienull
cią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 polegeo.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 kierunekasc
todesc
.
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