$geoNear (agregação)
Nesta página
Definição
$geoNear
Produz documentos na ordem do mais próximo para o mais distante de um ponto especificado.
Observação
O estágio
$geoNear
tem a seguinte forma de protótipo:{ $geoNear: { <geoNear options> } } O operador do
$geoNear
aceita um documento que contém as seguintes opções do$geoNear
. Especifique todas as distâncias nas mesmas unidades que as do sistema de coordenadas dos documentos processados:CampoTipoDescriçãodistanceField
stringO campo de saída que contém a distância calculada. Para especificar um campo em um documento incorporado, use a notação de ponto.distanceMultiplier
númeroOpcional. O fator para multiplicar todas as distâncias retornadas pela consulta. Por exemplo, utilize odistanceMultiplier
para converter radianos, como retornado por uma consulta esférica, para quilômetros multiplicando pelo raio da Terra.includeLocs
stringOpcional. Isto especifica o campo de saída que identifica o local utilizado para calcular a distância. Esta opção é útil quando um campo de localização contém múltiplos locais. Para especificar um campo dentro de um documento incorporado, use notação de ponto.key
Opcional. Especifique o campo indexado geoespacial para utilizar ao calcular a distância.
Se a sua coleção tiver múltiplos índices
2d
e/ou múltiplos índices2dsphere
, você deve utilizar a opçãokey
para especificar o caminho do campo indexado para utilizar. Especifique qual índice geoespacial usar fornece um exemplo completo.Se houver mais de um índice
2d
ou mais de um índice2dsphere
e você não especificar umkey
, MongoDB retornará um erro.Se você não especificar
key
e tiver no máximo apenas um índice2d
e/ou apenas um índice2dsphere
, o MongoDB procurará primeiro um índice2d
para usar. Se um índice2d
não existir, o MongoDB procurará um índice2dsphere
para usar.maxDistance
númeroOpcional. A distância máxima do ponto central que os documentos podem estar. O MongoDB limita os resultados aos documentos que se enquadram dentro da distância especificada a partir do ponto central. A partir da versão 7.2, você pode especificar uma expressão constante válida que se resolve em um número.
Especifique a distância em metros se o ponto especificado for GeoJSON e em radianos se o ponto especificado for pares de coordenadas legadas.
minDistance
númeroOpcional. A distância mínima do ponto central na qual os documentos podem estar. O MongoDB limita os resultados aos documentos que estão fora da distância especificada do ponto central. A partir da versão 7.2, você pode especificar uma expressão constante válida que se resolve em um número.
Especifique a distância em metros para dados GeoJSON e em radianos para pares de coordenadas legadas.
near
Ponto GeoJSON ou par de coordenadas legadoquery
documentoOpcional. Limita os resultados aos documentos que correspondem à consulta. A sintaxe de consulta é a sintaxe habitual de consulta de operação de leitura MongoDB.
Você não pode especificar um predicado
$near
no campoquery
do estágio$geoNear
.spherical
booleanoOpcional. Determina como MongoDB calcula a distância entre dois pontos:
Quando
true
, MongoDB utiliza semântica do$nearSphere
e calcula distâncias utilizando geometria esférica.Quando
false
, MongoDB utiliza semântica$near
: geometria esférica para índices 2dsphere e geometria planar para índices 2d.
Padrão: false.
Comportamento
Se utilizar o $geoNear
, considere que:
Você só pode utilizar
$geoNear
como o primeiro estágio de um pipeline.Você deve incluir a opção
distanceField
. A opçãodistanceField
especifica o campo que conterá a distância calculada.$geoNear
requer um índice geoespacial.Se você tiver mais de um índice geoespacial na coleção, use o parâmetro
keys
para especificar qual campo usar no cálculo. Se você tiver somente um índice geoespacial,$geoNear
implicitamente usará o campo indexado no cálculo.
Você não pode especificar um predicado
$near
no campoquery
do estágio$geoNear
.$geoNear
não tem mais um limite-padrão de 100 documentos.A partir do MongoDB 5.1, o parâmetro
near
é compatível com a opção let e opção bound let.A partir do MongoDB 5.3, você pode usar o operador de pipeline
$geoNear
em qualquer campo em uma coleção de séries temporais.A partir do MongoDB 6.0, você pode criar índices parciais e de 2dsphere em qualquer campo de uma coleção de séries temporais.
Começando no MongoDB 8.0,
$near
,$nearSphere
e$geoNear
, valide que o tipo dos pontos GeoJSON especificados éPoint
. Qualquer outro tipo de entrada retorna um erro.
Exemplos
Crie uma collection places
com os seguintes documentos:
db.places.insertMany( [ { name: "Central Park", location: { type: "Point", coordinates: [ -73.97, 40.77 ] }, category: "Parks" }, { name: "Sara D. Roosevelt Park", location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] }, category: "Parks" }, { name: "Polo Grounds", location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] }, category: "Stadiums" } ] )
A seguinte operação cria um índice 2dsphere
no campo location
:
db.places.createIndex( { location: "2dsphere" } )
Distância máxima
Observação
A coleção places
acima tem um índice 2dsphere
. A agregação a seguir utiliza $geoNear
para encontrar documentos com localização de no máximo 2 metros do centro [ -73.99279 , 40.719296 ]
e category
igual a Parks
.
db.places.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] }, distanceField: "dist.calculated", maxDistance: 2, query: { category: "Parks" }, includeLocs: "dist.location", spherical: true } } ])
A agregação retorna o seguinte:
{ "_id" : 8, "name" : "Sara D. Roosevelt Park", "category" : "Parks", "location" : { "type" : "Point", "coordinates" : [ -73.9928, 40.7193 ] }, "dist" : { "calculated" : 0.9539931676365992, "location" : { "type" : "Point", "coordinates" : [ -73.9928, 40.7193 ] } } }
O documento correspondente contém dois novos campos:
dist.calculated
campo que contém a distância calculada edist.location
que contém o local utilizado no cálculo.
Distância mínima
Observação
O exemplo seguinte utiliza a opção minDistance
para especificar a distância mínima do ponto central que os documentos podem ser. A seguinte aggregation encontra todos os documentos com um local a pelo menos 2 metros do centro [ -73.99279 , 40.719296 ]
e category
igual a Parks
.
db.places.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] }, distanceField: "dist.calculated", minDistance: 2, query: { category: "Parks" }, includeLocs: "dist.location", spherical: true } } ])
$geoNear com a let
opção
Neste exemplo:
A opção
let
é utilizada para definir um valor de array de[-73.99279,40.719296]
para a variável$pt
.$pt
é especificado como uma opçãolet
para o parâmetronear
no estágio$geoNear
.
db.places.aggregate( [ { "$geoNear": { "near":"$$pt", "distanceField":"distance", "maxDistance":2, "query":{"category":"Parks"}, "includeLocs":"dist.location", "spherical":true } } ], { "let":{ "pt": [ -73.99279, 40.719296 ] } } )
A agregação retorna todos os documentos com:
Um local a no máximo 2 metros do ponto definido na variável
let
Um
category
igual aParks
.
{ _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', distance: 1.4957325341976439e-7, dist: { location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] } } }, { _id: ObjectId("61715cf9b0c1d171bb498fd6"), name: 'Central Park', location: { type: 'Point', coordinates: [ -73.97, 40.77 ] }, category: 'Parks', distance: 0.0009348548688841822, dist: { location: { type: 'Point', coordinates: [ -73.97, 40.77 ] } } }
$geoNear com let
opçãobound
A opção let
pode vincular uma variável que pode ser utilizada em uma query $geoNear.
Neste exemplo, o $lookup
utiliza:
db.places.aggregate( [ { $lookup: { from: "places", let: { pt: "$location" }, pipeline: [ { $geoNear: { near: "$$pt", distanceField: "distance" } } ], as: "joinedField" } }, { $match: { name: "Sara D. Roosevelt Park" } } ] );
A agregação retorna um documento com:
O documento "Sara D. Roosevelt Park" como o documento principal.
Cada documento na coleção de locais como subDocumentos usando a variável
$pt
para calcular a distância.
{ _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', joinedField: [ { _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', distance: 0 }, { _id: ObjectId("61715cf9b0c1d171bb498fd6"), name: 'Central Park', location: { type: 'Point', coordinates: [ -73.97, 40.77 ] }, category: 'Parks', distance: 5962.448255234964 }, { _id: ObjectId("61715cfab0c1d171bb498fd8"), name: 'Polo Grounds', location: { type: 'Point', coordinates: [ -73.9375, 40.8303 ] }, category: 'Stadiums', distance: 13206.535424939102 } ] }
Especifique qual índice geoespacial usar
Considere uma coleção places
que tenha um índice 2dsphere no campo location
e um índice 2d no campo legacy
.
Um documento na collection places
se assemelha a:
{ "_id" : 3, "name" : "Polo Grounds", "location": { "type" : "Point", "coordinates" : [ -73.9375, 40.8303 ] }, "legacy" : [ -73.9375, 40.8303 ], "category" : "Stadiums" }
O exemplo a seguir usa a opção key
para especificar que a agregação deve usar os valores do campo location
para a operação $geoNear
e não os valores do campo legacy
. O pipeline também usa $limit
para retornar no máximo 5 documentos.
Observação
db.places.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [ -73.98142 , 40.71782 ] }, key: "location", distanceField: "dist.calculated", query: { "category": "Parks" } } }, { $limit: 5 } ])
A agregação retorna o seguinte:
{ "_id" : 8, "name" : "Sara D. Roosevelt Park", "location" : { "type" : "Point", "coordinates" : [ -73.9928, 40.7193 ] }, "category" : "Parks", "dist" : { "calculated" : 974.175764916902 } } { "_id" : 1, "name" : "Central Park", "location" : { "type" : "Point", "coordinates" : [ -73.97, 40.77 ] }, "legacy" : [ -73.97, 40.77 ], "category" : "Parks", "dist" : { "calculated" : 5887.92792958097 } }