Definición
$geoNearGenera documentos en orden del más cercano al más lejano desde un punto específico.
Nota
La etapa
$geoNeartiene la siguiente forma de prototipo:{ $geoNear: { <geoNear options> } } El operador
$geoNearacepta un documento que contiene las siguientes opciones$geoNear. Especifique todas las distancias en las mismas unidades que las del sistema de coordenadas de los documentos procesados:CampoTipoDescripcióndistanceFieldstring
El campo de salida que contiene la distancia calculada. Para especificar un campo dentro de un documento incrustado, utilice la notación de puntos.
distanceMultiplierNúmero
Opcional. El factor para multiplicar todas las distancias devueltas por la consulta. Por ejemplo, use
distanceMultiplierpara convertir radianes, como los devueltos por una consulta esférica, a kilómetros multiplicándolos por el radio de la Tierra.includeLocsstring
Opcional. Especifica el campo de salida que identifica la ubicación utilizada para calcular la distancia. Esta opción es útil cuando un campo de ubicación contiene varias ubicaciones. Para especificar un campo dentro de un documento incrustado, utilice la notación de puntos.
keyOpcional. Especifique el campo indexado geoespacial que se utilizará al calcular la distancia.
Si su colección tiene
2dvarios2dsphereíndices o,debe usar lakeyopción para especificar la ruta del campo indexado. En "Especificar quéíndice geoespacial usar" se ofrece un ejemplo completo.Si hay más de un índice
2do más de un índice2dspherey no especifica unkey, MongoDB devolverá un error.Si no especifica
keyy solo tiene un índice2do un índice2dspherecomo máximo, MongoDB busca primero un índice2d. Si no existe un índice2d, MongoDB busca un índice2dsphere.maxDistanceNúmero
Opcional. La distancia máxima desde el punto central a la que pueden estar los documentos. MongoDB limita los resultados a los documentos que se encuentran dentro de la distancia especificada desde el punto central.
Especifique la distancia en metros si el punto especificado es GeoJSON y en radianes si el punto especificado son pares de coordenadas heredados.
minDistanceNúmero
Opcional. La distancia mínima desde el punto central a la que pueden estar los documentos. MongoDB limita los resultados a los documentos que se encuentran fuera de la distancia especificada desde el punto central.
Especifique la distancia en metros para los datos GeoJSON y en radianes para los pares de coordenadas heredados.
nearPunto GeoJSON o par de coordenadas heredadas
El punto donde encontrar los documentos más cercanos.
Si utiliza un índice 2dsphere, puede especificar el punto como un punto GeoJSON o un par de coordenadas heredadas.
Si utiliza un índice d, especifique el punto como un par de coordenadas 2 heredado.
queryDocumento
sphericalbooleano
Opcional. Determina cómo MongoDB calcula la distancia entre dos puntos:
trueCuando, MongoDB utiliza la semántica y calcula distancias utilizando geometría$nearSphereesférica.falseCuando, MongoDB utiliza semántica:$neargeometría esférica para índices 2dsphere y geometría 2plana para índices d.
Por defecto: falso.
Comportamiento
Cálculos de distancia
$geoNear Calcula la distancia basándose en el punto más cercano del perímetro del documento de entrada.
Por ejemplo, si el documento de entrada es una forma, identifica el punto en el perímetro de la forma que está más cerca del punto especificado y genera la distancia entre el punto especificado y el punto más cercano de la$geoNear forma.
Considerations
Al utilizar, tenga $geoNear en cuenta que:
Solo puedes usar como la primera etapa de una
$geoNearcanalización.Debe incluir la opción
distanceField. La opcióndistanceFieldespecifica el campo que contendrá la distancia calculada.$geoNearrequiere un índice geoespacial.Si tiene más de un índice geoespacial en la colección, utilice
keysel parámetro para especificar qué campo usar en el cálculo. Si solo tiene un índice geoespacial,$geoNearutiliza implícitamente el campo indexado para el cálculo.
No se puede especificar un predicado en
$nearelquerycampo de la$geoNearetapa.$geoNearya no tiene un límite predeterminado de 100 documentos.A partir de MongoDB,5.1 el
nearparámetro admite la opción let y la opción let enlazada.A partir de MongoDB,5.3 puede utilizar el
$geoNearoperador de canalización en cualquier campo de una colección de series de tiempo.A partir de MongoDB,6.0 puede crear índices parciales y 2dsphere en cualquier campo de una colección de series de tiempo.
Ejemplos
Cree una colección places con los siguientes 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" } ] )
La siguiente operación crea un índice 2dsphere en el campo location:
db.places.createIndex( { location: "2dsphere" } )
Distancia máxima
Nota
La places colección anterior tiene un 2dsphere índice. La siguiente agregación utiliza para buscar documentos con una ubicación a un máximo $geoNear de 2 metros del centro [ -73.99279 , 40.719296 ] y category igual Parks a.
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 } } ])
La agregación devuelve lo siguiente:
{ "_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 ] } } }
El documento coincidente contiene dos campos nuevos:
dist.calculatedcampo que contiene la distancia calculada, ydist.locationcampo que contiene la ubicación utilizada en el cálculo.
Distancia mínima
Nota
El siguiente ejemplo utiliza la opción minDistance para especificar la distancia mínima desde el centro a la que pueden estar los documentos. La siguiente agregación busca todos los documentos con una ubicación al menos a 2 metros del centro [ -73.99279 , 40.719296 ] y 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 con la opción let
En este ejemplo:
La opción
letse utiliza para establecer un valor de matriz de[-73.99279,40.719296]en la variable$pt.$ptse especifica como una opciónletpara el parámetronearen la etapa$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 ] } } )
La agregación retorna todos los documentos con:
Una ubicación a máximo 2 metros del punto definido en la variable
letUn
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 con opción let enlazada
La opción let puede vincular una variable que puede usarse en una consulta $geoNear.
En este ejemplo, $lookup utiliza:
letpara definir$pt.$geoNearenpipelineel.$ptpara definirnearen la etapa de$geoNearcanalización.
db.places.aggregate( [ { $lookup: { from: "places", let: { pt: "$location" }, pipeline: [ { $geoNear: { near: "$$pt", distanceField: "distance" } } ], as: "joinedField" } }, { $match: { name: "Sara D. Roosevelt Park" } } ] );
La agregación devuelve un documento con:
El documento 'Sara D. Roosevelt Park' como documento principal.
Cada documento de la colección de lugares como subdocumentos que utilizan la variable
$ptpara calcular la distancia.
{ _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 qué índice geoespacial utilizar
Considere una places colección que tiene un índice 2dsphere en el location campo y un índice 2d en el legacy campo.
Un documento de la colección places se parece al siguiente:
{ "_id" : 3, "name" : "Polo Grounds", "location": { "type" : "Point", "coordinates" : [ -73.9375, 40.8303 ] }, "legacy" : [ -73.9375, 40.8303 ], "category" : "Stadiums" }
El siguiente ejemplo utiliza la key opción para especificar que la agregación debe usar los location valores de campo para la operación en lugar de $geoNear los legacy valores de campo. La canalización también utiliza para devolver un máximo $limit de 5 documentos.
Nota
db.places.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [ -73.98142 , 40.71782 ] }, key: "location", distanceField: "dist.calculated", query: { "category": "Parks" } } }, { $limit: 5 } ])
La agregación devuelve lo siguiente:
{ "_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 } }
Los ejemplos de C# de esta página utilizan la sample_mflix.theaters colección de los conjuntos de datos de ejemplo de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de ejemplo, consulte la sección "Comenzar" en la documentación del controlador MongoDB.NET/C#.
Las siguientes clases Theater, Location y Address modelan los documentos de la colección 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 el controlador MongoDB.NET/C# para agregar una $geoNear etapa a una canalización de agregación, llame a GeoNear()método en un PipelineDefinition objeto.
Este método solo está disponible en el controlador MongoDB .NET/C# v3.4 y versiones posteriores.
Distancia máxima
El siguiente ejemplo crea una etapa de canalización que devuelve documentos en un radio de 8000 metros del punto especificado, ordenados de forma ascendente. El código incluye un parámetro Query que solo coincide con los documentos cuyo valor del campo location.address.state es "NJ". El código también almacena la distancia calculada en el campo distance de los documentos de salida.
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"), });
Distancia mínima
El siguiente ejemplo devuelve los primeros 4 documentos coincidentes fuera de un radio de 8000 metros del punto especificado, en orden ascendente de distancia. El código incluye un parámetro Query que solo coincide con los documentos cuyo valor del campo location.address.state es "NJ". El código también almacena la distancia calculada en el campo distance de los documentos de salida.
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);
Los ejemplos de Node.js en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte Primeros pasos en la documentación del controlador de MongoDB Node.js.
Para utilizar el controlador de MongoDB Node.js para agregar una etapa de $geoNear a una canalización de agregación, utilice el Operador $geoNear en un objeto de canalización.
Distancia máxima
El siguiente ejemplo crea una etapa de canalización que devuelve documentos en un radio de 8000 metros del punto especificado, ordenados de forma ascendente. El código incluye un campo query que solo coincide con los documentos cuyo valor del campo location.address.state es "NJ". El código también almacena la distancia calculada en el campo distance de los documentos de salida. A continuación, el ejemplo ejecuta la canalización de agregación:
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;
Distancia mínima
El siguiente ejemplo devuelve los primeros 4 documentos coincidentes fuera de un radio de 8000 metros del punto especificado, en orden ascendente de distancia. El código incluye un campo query que solo coincide con los documentos cuyo valor del campo location.address.state es "NJ". El código también almacena la distancia calculada en el campo distance de los documentos de salida:
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;
Obtén más información
Para aprender más sobre las etapas relacionadas del pipeline, consulta la guía $limit.