OData-Geofunktionen in Azure KI Search: geo.distance
und geo.intersects
Azure KI Search unterstützt Geoabfragen in OData-Filterausdrücken über die Funktionen geo.distance
und geo.intersects
. Die Funktion geo.distance
gibt die Entfernung zwischen zwei Punkten in Kilometern zurück, wobei es sich bei einem Punkt um ein Feld oder eine Bereichsvariable und bei dem anderen Punkt um eine Konstante handelt, die als Teil des Filters übergeben wird. Die Funktion geo.intersects
gibt true
zurück, wenn ein bestimmter Punkt innerhalb eines bestimmten Polygons liegt. Der Punkt ist hierbei ein Feld oder eine Bereichsvariable, und das Polygon wird als Konstante als Teil des Filters übergeben.
Die Funktion geo.distance
kann auch im Parameter $orderby verwendet werden, um Suchergebnisse nach der Entfernung von einem bestimmten Punkt zu sortieren. Die Syntax für geo.distance
in $orderby entspricht der Syntax in $filter. Bei Verwendung von geo.distance
in $orderby muss das Feld, für das die Funktion gilt, vom Typ Edm.GeographyPoint
und zudem sortierbar sein.
Hinweis
Wenn Sie geo.distance
im $orderby-Parameter verwenden, darf das Feld, das Sie an die Funktion übergeben, nur einen einzigen geografischen Punkt enthalten. Anders ausgedrückt, es muss vom Typ Edm.GeographyPoint
und nicht Collection(Edm.GeographyPoint)
sein. Es ist nicht möglich, in Azure KI Search nach Sammlungsfeldern zu sortieren.
Syntax
Die folgende erweiterte Backus-Naur-Form (EBNF) definiert die Grammatik der Funktionen geo.distance
und geo.intersects
sowie die Geowerte, für die sie ausgeführt werden:
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)*
Ein interaktives Syntaxdiagramm ist ebenfalls verfügbar:
Hinweis
Die vollständige EBNF finden Sie in der Referenz zur OData-Ausdruckssyntax für Azure KI Search.
geo.distance
Die Funktion geo.distance
akzeptiert zwei Parameter vom Typ Edm.GeographyPoint
und gibt einen Wert vom Typ Edm.Double
zurück, der die Entfernung zwischen diesen in Kilometern angibt. Im Unterschied dazu werden bei anderen Diensten, die OData-Geovorgänge unterstützen, Entfernungen in der Regel in Metern zurückgegeben.
Einer der Parameter für geo.distance
muss eine Konstante des geografischen Punkts sein, und der andere muss ein Feldpfad (oder eine Bereichsvariable im Fall einer Filteriteration über ein Feld vom Typ Collection(Edm.GeographyPoint)
) sein. Die Reihenfolge dieser Parameter spielt keine Rolle.
Die Konstante des geografischen Punkts weist das Format geography'POINT(<longitude> <latitude>)'
auf, wobei Längengrad und Breitengrad numerische Konstanten sind.
Hinweis
Wenn Sie geo.distance
in einem Filter verwenden, müssen Sie die von der Funktion zurückgegebene Entfernung mithilfe von lt
, le
, gt
oder ge
mit einer Konstante vergleichen. Die Operatoren eq
und ne
werden beim Vergleichen von Entfernungen nicht unterstützt. Hier ist ein Beispiel für die korrekte Verwendung von geo.distance
: $filter=geo.distance(location, geography'POINT(-122.131577 47.678581)') le 5
.
geo.intersects
Die Funktion geo.intersects
akzeptiert eine Variable vom Typ Edm.GeographyPoint
und eine Konstante vom Typ Edm.GeographyPolygon
und gibt einen Wert Edm.Boolean
-- true
zurück, wenn sich der Punkt innerhalb der Grenzen des Polygons befindet. Andernfalls wird false
zurückgegeben.
Das Polygon ist eine zweidimensionale Fläche und wird als eine Reihe von Punkten gespeichert, die einen Begrenzungsring definieren (siehe unten stehende Beispiele). Das Polygon muss geschlossen sein, d. h. der erste und der letzte Punkt müssen identisch sein. Punkte in einem Polygon müssen entgegen dem Uhrzeigersinn angegeben werden.
Geoabfragen und Polygone, die den 180. Längengrad umfassen
Bei vielen Bibliotheken für Geoabfragen ist die Erstellung einer Abfrage, die den 180. Längengrad (nahe der Datumsgrenze) umfasst, entweder nicht oder nur mithilfe einer Problemumgehung möglich, z. B. durch Aufteilung des Polygons in zwei Teile auf jeweils einer Seite des Längengrads.
In Azure KI Search funktionieren Geoabfragen mit dem 180. Längengrad wie erwartet, wenn die Form der Abfrage rechteckig ist und die Koordinaten von Längen- und Breitengrad an einem Rasterlayout ausgerichtet sind (z. B. geo.intersects(location, geography'POLYGON((179 65, 179 66, -179 66, -179 65, 179 65))'
). Erwägen Sie andernfalls für nicht rechteckige oder nicht ausgerichtete Formen die Aufteilung des Polygons.
Geofunktionen und null
Wie alle anderen Nicht-Sammlungsfelder in Azure KI Search können Felder vom Typ Edm.GeographyPoint
auch null
-Werte enthalten. Wenn Azure KI Search geo.intersects
für ein Feld auswertet, dessen Wert null
lautet, ist das Ergebnis immer false
. Das Verhalten von geo.distance
hängt in diesem Fall vom Kontext ab:
- In Filtern resultiert die
geo.distance
eines Felds mit dem Wertnull
innull
. Dies bedeutet, dass das Dokument nicht übereinstimmt, weilnull
im Vergleich zu jedem Wert ungleich NULL zufalse
ausgewertet wird. - Beim Sortieren von Ergebnissen mit $orderby ergibt die
geo.distance
eines Felds mit dem Wertnull
die größtmögliche Entfernung. Dokumente mit einem solchen Feld werden bei Verwendung der Sortierrichtungasc
(Standardeinstellung) niedriger als alle anderen und bei Verwendung der Sortierrichtungdesc
höher als alle anderen sortiert.
Beispiele
Filterbeispiele
Suche nach allen Hotels in einem Umkreis von 10 Kilometern von einem angegebenen Referenzpunkt (wobei „location“ ein Feld vom Typ Edm.GeographyPoint
ist):
geo.distance(location, geography'POINT(-122.131577 47.678581)') le 10
Suche nach allen Hotels in einem bestimmten Anzeigebereich, der als Polygon definiert ist (wobei „location“ ein Feld vom Typ Edm.GeographyPoint
ist). Beachten Sie, dass das Polygon geschlossen ist (der erste und der letzte Punkt müssen identisch sein), und die Punkte müssen entgegen dem Uhrzeigersinn aufgelistet sein.
geo.intersects(location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')
Beispiele für das Sortieren
Sortieren von Hotels in absteigender Reihenfolge nach rating
und anschließend in aufsteigender Reihenfolge nach der Entfernung von den angegebenen Koordinaten:
rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc
Sortieren von Hotels in absteigender Reihenfolge nach search.score
und rating
und anschließend in aufsteigender Reihenfolge nach der Entfernung von den angegebenen Koordinaten, sodass von zwei Hotels mit identischen Bewertungen das nächstgelegene zuerst aufgeführt wird:
search.score() desc,rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc