Definição
$geoNearProduz documentos na ordem do mais próximo para o mais distante de um ponto especificado.
Observação
O MongoDB remove as
limitnumopções$geoNeare do estágio, bem como o limite padrão de documentos.100 Para limitar os resultados de$geoNear, use o estágio$geoNearcom o estágio$limit.O estágio
$geoNeartem a seguinte forma de protótipo:{ $geoNear: { <geoNear options> } } O operador do
$geoNearaceita 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çãodistanceFieldstring
O 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.
distanceMultipliernúmero
Opcional. O fator para multiplicar todas as distâncias retornadas pela consulta. Por exemplo, utilize o
distanceMultiplierpara converter radianos, como retornado por uma consulta esférica, para quilômetros multiplicando pelo raio da Terra.includeLocsstring
Opcional. 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.
keyOpcional. Especifique o campo indexado geoespacial para utilizar ao calcular a distância.
Se a sua coleção tiver
2d2dspheremúltiplos índices e/ou múltiplos índices , você deve utilizar akeyopção para especificar o caminho do campo indexado para utilizar. Especificar qual índice geoespacial usar fornece um exemplo completo .Se houver mais de um índice
2dou mais de um índice2dspheree você não especificar umkey, MongoDB retornará um erro.Se você não especificar
keye tiver no máximo apenas um índice2de/ou apenas um índice2dsphere, o MongoDB procurará primeiro um índice2dpara usar. Se um índice2dnão existir, o MongoDB procurará um índice2dspherepara usar.maxDistancenúmero
Opcional. A distância máxima do ponto central na qual os documentos podem estar. O MongoDB limita os resultados aos documentos que se enquadram dentro da distância especificada a partir do ponto central.
Especifique a distância em metros se o ponto especificado for GeoJSON e em radianos se o ponto especificado for pares de coordenadas legadas.
minDistancenúmero
Opcional. 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.
Especifique a distância em metros para dados GeoJSON e em radianos para pares de coordenadas legadas.
nearPonto GeoJSON ou par de coordenadas legado
querydocumento
Opcional. 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
$nearnoquerycampo do$geoNearestágio .sphericalbooleano
Opcional. Determina como MongoDB calcula a distância entre dois pontos:
Quando
true, MongoDB utiliza semântica do$nearSpheree 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
Cálculos de distância
$geoNear calcula a distância com base no ponto mais próximo do parâmetro do documento de entrada.
Por exemplo, se o documento de entrada for uma forma, identificará o ponto no limite da forma que é mais próximo do ponto especificado e produzirá a distância entre o ponto especificado e o ponto mais próximo da$geoNear forma.
Considerações
Se utilizar o $geoNear, considere que:
Você só pode utilizar
$geoNearcomo o primeiro estágio de um pipeline.Você deve incluir a opção
distanceField. A opçãodistanceFieldespecifica o campo que conterá a distância calculada.$geoNearrequer um índice geoespacial.Se você tiver mais de um índice geoespacial na coleção, use o parâmetro
keyspara especificar qual campo usar no cálculo. Se você tiver somente um índice geoespacial,$geoNearimplicitamente usará o campo indexado no cálculo.
Você não pode especificar um predicado
$nearno campoquerydo estágio$geoNear.$geoNearnã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
$geoNearem 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.
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.calculatedcampo que contém a distância calculada edist.locationque 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çãoletpara o parâmetronearno 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
letUm
categoryigual 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
$ptpara 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 } }
Os exemplos de C# nesta página usam a collection sample_mflix.theaters dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver MongoDB .NET/C#.
As seguintes classes Theater, Location e Address modelam os documentos na coleção sample_mflix.theaters:
public class Theater { public ObjectId Id { get; set; } [] public int TheaterId { get; set; } [] public Location Location { get; set; } [] public double? Distance { get; set; } } public class Location { [] public Address Address { get; set; } [] public GeoJsonPoint<GeoJson2DGeographicCoordinates> Geo { get; set; } } [] public class Address { [] public string City { get; set; } [] public string State { get; set; } }
Para usar o driver MongoDB .NET/C# para adicionar um estágio $geoNear a um pipeline de agregação, chame o método GeoNear() em um objeto PipelineDefinition.
Este método está disponível apenas no MongoDB .NET/C# driver v3.4 e posterior.
Distância máxima
O exemplo a seguir cria um estágio de pipeline que retorna documentos em um raio de 8000 metros do ponto especificado, em ordem crescente de distância. O código inclui um parâmetro Query que apenas corresponde a documentos nos quais o valor do campo location.address.state é "NJ". O código também armazena a distância calculada no campo distance dos documentos de saída.
var pipeline = new EmptyPipelineDefinition<Theater>() .GeoNear( GeoJson.Point(GeoJson.Geographic(-74.1, 40.95)), new GeoNearOptions<Theater, Theater> { DistanceField = "distance", MaxDistance = 8000, Key = "location.geo", Query = Builders<Theater>.Filter.Eq(t => t.Location.Address.State, "NJ"), });
Distância mínima
O exemplo a seguir retorna os primeiros 4 documentos correspondentes fora de um raio de 8000 metros do ponto especificado , em ordem de distância crescente. O código inclui um parâmetro Query que só corresponde a documentos nos quais o valor do campo location.address.state é "NJ". O código também armazena a distância calculada no campo distance dos documentos de saída.
var pipeline = new EmptyPipelineDefinition<Theater>() .GeoNear( GeoJson.Point(GeoJson.Geographic(-74.1, 40.95)), new GeoNearOptions<Theater, Theater> { DistanceField = "distance", MinDistance = 8000, Key = "location.geo", Query = Builders<Theater>.Filter.Eq(t => t.Location.Address.State, "NJ"), }) .Limit(4);
Os exemplos do Node.js nesta página utilizam o banco de dados do sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js
Para usar o driver Node.js do MongoDB para adicionar um estágio $geoNear a um pipeline de agregação , use o operador $geoNear em um objeto de pipeline.
Distância máxima
O exemplo a seguir cria um estágio de pipeline que retorna documentos em um raio de 8000 metros do ponto especificado, em ordem de distância crescente. O código inclui um campo query que só corresponde a documentos em que o valor do campo location.address.state é "NJ". O código também armazena a distância calculada no campo distance dos documentos de saída. Em seguida, o exemplo executa o agregação pipeline:
const pipeline = [ { $geoNear: { near: { type: "Point", coordinates: [-74.1, 40.95] }, distanceField: "distance", maxDistance: 8000, query: { "location.address.state": "NJ" }, spherical: true } } ]; const cursor = collection.aggregate(pipeline); return cursor;
Distância mínima
O exemplo a seguir retorna os primeiros 4 documentos correspondentes fora de um raio de 8000 metros do ponto especificado , em ordem de distância crescente. O código inclui um campo query que só corresponde a documentos em que o valor do campo location.address.state é "NJ". O código também armazena a distância calculada no campo distance dos documentos de saída:
const pipeline = [ { $geoNear: { near: { type: "Point", coordinates: [-74.1, 40.95] }, distanceField: "distance", minDistance: 8000, query: { "location.address.state": "NJ" }, spherical: true }, }, { $limit: 4 } ]; const cursor = collection.aggregate(pipeline); return cursor;
Saiba mais
Para saber mais sobre os estágios de pipeline relacionados, consulte o guia$limit.