Overview
En esta guía, aprenderá a query datos geoespaciales utilizando el driver de Scala. También puedes aprender sobre los diferentes formatos de datos geoespaciales compatibles con MongoDB.
Los datos geoespaciales representan una ubicación geográfica en la superficie de la Tierra. Ejemplos de datos geoespaciales incluyen:
Ubicaciones de cines
Fronteras de los países
Rutas de paseos en bicicleta
Áreas para ejercitar perros en Nueva York
Datos de muestra
Los ejemplos de esta guía utilizan la colección theaters en la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para acceder a esta colección desde tu aplicación Scala, crea un MongoClient que se conecte a un clúster Atlas y asigna los siguientes valores a tus variables database y collection:
val database: MongoDatabase = mongoClient.getDatabase("sample_mflix") val collection: MongoCollection[Document] = database.getCollection("theaters")
Para aprender cómo crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de ejemplo, consulta la guía MongoDB Get Started.
Coordenadas en la Tierra
Para almacenar y realizar consultas sobre tus datos geoespaciales en MongoDB, utiliza GeoJSON. GeoJSON es un formato de datos creado por el Grupo de Trabajo de Ingeniería de Internet (IETF).
Esta es la ubicación de la sede de MongoDB en GeoJSON:
"location" : { "type": "Point", "coordinates": [-73.986805, 40.7620853] }
Para obtener información definitiva sobre GeoJSON, consulte la especificación oficial de IETF.
Posiciones GeoJSON
Una posición representa un único lugar en la Tierra y se define como un arreglo que contiene dos o tres valores numéricos:
Longitud en la primera posición (requerido)
Latitud en la segunda posición (obligatoria).
Elevación en la tercera posición (opcional)
Importante
Longitud y luego latitud
GeoJSON ordena las coordenadas como primero longitud y segundo latitud. Esto puede ser sorprendente, ya que las convenciones del sistema de coordenadas geográficas generalmente indican la latitud primero y la longitud después. Asegúrate de comprobar qué formato utilizan las demás herramientas con las que trabajas. Las herramientas populares, como OpenStreetMap y Google Maps, enumeran las coordenadas como latitud primero y longitud segundo.
Tipos GeoJSON
El tipo del objeto GeoJSON determina su forma geométrica. Las formas geométricas se componen de posiciones.
Aquí tienes algunos tipos comunes de GeoJSON y cómo puedes especificarlos con posiciones:
PointUna sola posición. Esto podría representar la ubicación de una escultura.LineString: arreglo de dos o más posiciones, formando así una serie de segmentos de línea. Esto podría representar la ruta de la Gran Muralla China.Polygon: Arreglo de posiciones en las que la primera y la última posición son iguales, encerrando algún espacio. Esto podría representar la tierra dentro de la Ciudad del Vaticano.
Para aprender más sobre las formas que puedes usar en MongoDB, consulta GeoJSON en el manual del Servidor.
Index
Para crear un índice 2dsphere, utiliza el asistente Indexes.geo2dsphere() para crear una especificación para el índice 2dsphere. Pase la especificación al método MongoCollection.createIndex() para crear el índice.
El siguiente ejemplo crea un índice 2dsphere en el campo "location.geo" en la colección theaters:
val indexObservable = collection.createIndex(Indexes.geo2dsphere("location.geo")) Await.result(indexObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
Para aprender más sobre los índices en el driver de Scala, consulta la guía Optimiza query mediante índice.
Coordenadas en un plano 2D
Puede almacenar datos geoespaciales utilizando las coordenadas x y y en un plano euclidiano bidimensional. Las coordenadas en un plano bidimensional se denominan legacy coordinate pairs.
Los pares de coordenadas heredadas tienen la siguiente estructura:
{ "location" : [ x, y ] }
El valor del campo contiene un arreglo de dos valores en la que el primero representa el valor del eje x y el segundo representa el valor del eje y.
Index
Para query datos almacenados como legacy coordinate pairs, debe agregar el campo que contiene los legacy coordinate pairs a un índice 2d. El siguiente snippet crea un índice 2d en el campo coordinates utilizando el objeto Indexes:
val indexObservable = collection.createIndex(Indexes.geo2d("coordinates")) Await.result(indexObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
Para aprender más sobre los índices en el driver de Scala, consulta la guía Optimiza query mediante índice.
Para obtener más información sobre legacy coordinate pairs, consulta la sección legacy coordinate pairs de la guía de Queries Geoespaciales en el manual del Server.
Tip
Operadores compatibles
Los índices esféricos (2dsphere) y planos (2d) admiten algunos, pero no todos, los mismos operadores del query. Para ver una lista completa de operadores y su compatibilidad con índices, consulta la sección de Operadores del query geoespaciales en la guía de Consultas geoespaciales del manual del servidor.
Query geoespacial
Las consultas geoespaciales consisten en un operador del query y formas GeoJSON como parámetros del query.
Operadores del query
Para query tus datos geoespaciales, utiliza uno de los siguientes operadores del query:
$near$geoWithin$nearSphere$geoIntersectsrequiere un índice 2dsphere
Puedes especificar estos operadores del query en el driver de Scala con los métodos near(), geoWithin(), nearSphere() y geoIntersects() del objeto Filters.
Para obtener más información sobre los operadores del query geoespacial, consulta la sección Operadores de Consulta Geoespacial de la guía Consultas Geoespaciales en el Manual del servidor.
Para ver una lista completa de los métodos asistentes de Filters, consulte la Filtros documentación de la API.
Parámetros de query
Para especificar una forma que se utilizará en una query geoespacial, utilice las clases Position, Point, LineString y Polygon del driver de Scala.
Para obtener más información sobre las clases de formas de GeoJSON, consulte la paquete GeoJSON Documentación de la API.
Ejemplos de consultas geoespaciales
Los siguientes ejemplos utilizan la colección theaters de MongoDB Atlas en la base de datos de muestra sample_mflix. Puedes aprender cómo configurar tu propio clúster Atlas de nivel gratuito y cómo cargar el conjunto de datos de ejemplo en la guía "Primeros pasos con el controlador Scala".
Los ejemplos de esta sección requieren las siguientes importaciones:
import org.mongodb.scala.* import org.mongodb.scala.model.Indexes import org.mongodb.scala.model.Filters import org.mongodb.scala.model.Projections import com.mongodb.client.model.geojson.{Point, Polygon, Position} import java.util.Arrays import java.util.concurrent.TimeUnit import scala.concurrent.Await import scala.concurrent.duration.Duration
La colección theaters ya contiene un índice 2dsphere en el campo location.geo.
Query por Proximidad
Para buscar y devolver documentos desde el más cercano al más lejano a un punto, utiliza el método near() del objeto Filters. El método near() construye una query con el operador del query $near.
El siguiente ejemplo devuelve documentos que están como máximo a 1000 metros de la instancia especificada de GeoJSON Point, ordenados del más cercano al más lejano:
val refPoint = new Point(new Position(-73.986805, 40.7620853)) val findObservable = collection.find(Filters.near("location.geo", refPoint, Some(1000.0), Some(0.0))) val results = Await.result(findObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
Tip
MongoDB usa el mismo sistema de referencias que los satélites GPS para calcular geometrías sobre la Tierra.
Para aprender más sobre el operador $near, consulta la referencia $near en el manual del servidor.
Consulta dentro de un rango
Para buscar datos geoespaciales dentro de una forma especificada, utilice el método geoWithin() del objeto Filters. El método geoWithin() construye una query con el operador del query $geoWithin.
El siguiente ejemplo busca salas de cine en una sección de Long Island. El ejemplo aplica una proyección para que cada resultado incluya solo el campo location.address.city y excluya el campo _id:
val longIslandTriangle = new Polygon(Arrays.asList( new Position(-72.0, 40.0), new Position(-74.0, 41.0), new Position(-72.0, 39.0), new Position(-72.0, 40.0) )) val projection = Projections.fields( Projections.include("location.address.city"), Projections.excludeId() ) val geoWithinComparison = Filters.geoWithin("location.geo", longIslandTriangle) val findObservable = collection.find(geoWithinComparison).projection(projection) val results = Await.result(findObservable.toFuture(), Duration(10, TimeUnit.SECONDS)) results.foreach(doc => println(doc.toJson()))
La figura siguiente muestra el polígono definido por la variable longIslandTriangle y puntos que representan las ubicaciones de los cines que devuelve la query.

Para aprender más sobre el operador $geoWithin, consulta la referencia $geoWithin en el manual del Servidor.
Información Adicional
Para obtener más información sobre cómo realizar consultas geoespaciales, consulta Consultas geoespaciales en el manual del servidor.