Partilhar via


Funções geoespaciais OData no Azure AI Search - geo.distance e geo.intersects

O Azure AI Search dá suporte a consultas geoespaciais em expressões de filtro OData por meio das geo.distance funções e geo.intersects . A geo.distance função retorna a distância em quilômetros entre dois pontos, sendo um campo ou variável de intervalo e outro uma constante passada como parte do filtro. A geo.intersects função retorna true se um determinado ponto estiver dentro de um determinado polígono, onde o ponto é uma variável de campo ou intervalo e o polígono é especificado como uma constante passada como parte do filtro.

A geo.distance função também pode ser usada no parâmetro $orderby para classificar os resultados da pesquisa por distância de um determinado ponto. A sintaxe para geo.distance in $orderby é a mesma que em $filter. Ao usar geo.distance em $orderby, o campo ao qual se aplica deve ser do tipo Edm.GeographyPoint e também deve ser classificável.

Nota

Ao usar geo.distance no parâmetro $orderby , o campo que você passa para a função deve conter apenas um único geoponto. Por outras palavras, deve ser do tipo Edm.GeographyPoint e não Collection(Edm.GeographyPoint). Não é possível classificar em campos de coleção no Azure AI Search.

Sintaxe

A seguinte EBNF (Extended Backus-Naur Form) define a gramática das e geo.intersects funções, bem como os valores geoespaciais sobre os geo.distance quais operam:

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

Um diagrama de sintaxe interativo também está disponível:

Nota

Consulte Referência de sintaxe de expressão OData para Azure AI Search para obter o EBNF completo.

geo.distância

A geo.distance função usa dois parâmetros do tipo Edm.GeographyPoint e retorna um Edm.Double valor que é a distância entre eles em quilômetros. Isso difere de outros serviços que suportam operações geoespaciais OData, que normalmente retornam distâncias em metros.

Um dos parâmetros deve geo.distance ser uma constante de ponto geográfico, e o outro deve ser um caminho de campo (ou uma variável de intervalo no caso de um filtro iterando sobre um campo do tipo Collection(Edm.GeographyPoint)). A ordem desses parâmetros não importa.

A constante do ponto geográfico é da forma geography'POINT(<longitude> <latitude>)', onde a longitude e a latitude são constantes numéricas.

Nota

Ao usar geo.distance em um filtro, você deve comparar a distância retornada pela função com uma constante usando lt, le, gt, ou ge. Os operadores eq e ne não são suportados ao comparar distâncias. Por exemplo, este é um uso correto de geo.distance: $filter=geo.distance(location, geography'POINT(-122.131577 47.678581)') le 5.

geo.intersects

A geo.intersects função usa uma variável de tipo Edm.GeographyPoint e uma constante Edm.GeographyPolygon e retorna um Edm.Boolean -- true se o ponto estiver dentro dos limites do polígono, false caso contrário.

O polígono é uma superfície bidimensional armazenada como uma sequência de pontos que definem um anel delimitador (veja os exemplos abaixo). O polígono precisa ser fechado, o que significa que o primeiro e o último conjuntos de pontos devem ser os mesmos. Os pontos em um polígono devem estar em ordem anti-horário.

Consultas geoespaciais e polígonos que abrangem o meridiano 180

Para muitas bibliotecas de consulta geoespacial, formular uma consulta que inclua o meridiano 180 (perto da linha de data) está fora dos limites ou requer uma solução alternativa, como dividir o polígono em dois, um de cada lado do meridiano.

No Azure AI Search, as consultas geoespaciais que incluem longitude de 180 graus funcionarão conforme o esperado se a forma de consulta for retangular e suas coordenadas se alinharem a um layout de grade ao longo da longitude e latitude (por exemplo, geo.intersects(location, geography'POLYGON((179 65, 179 66, -179 66, -179 65, 179 65))'). Caso contrário, para formas não retangulares ou não alinhadas, considere a abordagem de polígono dividido.

Funções geoespaciais e null

Como todos os outros campos não colecionáveis no Azure AI Search, os campos do tipo Edm.GeographyPoint podem conter null valores. Quando o geo.intersects Azure AI Search for avaliado para um campo que é null, o resultado será sempre false. O comportamento deste geo.distance caso depende do contexto:

  • Em filtros, geo.distance de um null campo resulta em null. Isso significa que o documento não corresponderá porque null , em comparação com qualquer valor não nulo, é avaliado como false.
  • Ao classificar os resultados usando $orderby, geo.distance de um null campo resulta na distância máxima possível. Os documentos com esse campo classificarão mais baixo do que todos os outros quando a direção asc de classificação for usada (o padrão) e mais alto do que todos os outros quando a direção for desc.

Exemplos

Exemplos de filtros

Encontre todos os hotéis a menos de 10 km de um determinado ponto de referência (onde a localização é um campo do tipo Edm.GeographyPoint):

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

Encontre todos os hotéis dentro de um determinado visor descrito como um polígono (onde a localização é um campo do tipo Edm.GeographyPoint). Observe que o polígono está fechado (o primeiro e o último conjuntos de pontos devem ser os mesmos) e os pontos devem ser listados no sentido anti-horário.

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

Exemplos por ordem

Ordene os hotéis descendo por ratinge, em seguida, subindo por distância das coordenadas dadas:

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

Classifique os hotéis em ordem decrescente por search.score e ratinge, em seguida, em ordem crescente por distância das coordenadas dadas, de modo que, entre dois hotéis com classificações idênticas, o mais próximo seja listado primeiro:

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

Próximos passos