Overview
En esta guía aprenderás cómo hacer query de datos geoespaciales usando el driver de Kotlin. También puedes aprender sobre los diferentes formatos de datos geoespaciales admitidos por MongoDB.
Los datos geoespaciales son datos que representan una ubicación geográfica en la superficie de la Tierra. Los 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
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 el especificación oficial del 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 luego latitud
GeoJSON ordena las coordenadas como longitud primero y latitud después. Esto puede resultar sorprendente, ya que las convenciones de los sistemas de coordenadas geográficas generalmente indican la latitud primero y la longitud después. Asegúrate de verificar el formato que usan otras herramientas con las que trabajas. Herramientas populares como OpenStreetMap y Google Maps indican las coordenadas como latitud primero y longitud después.
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.LineStringMatriz 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 obtener más información sobre las formas que puede utilizar en MongoDB, consulte GeoJSON en el manual del servidor.
Index
Para consultar datos almacenados en formato GeoJSON, agregue el campo que contiene datos GeoJSON a un índice 2dsphere. El siguiente fragmento crea un índice 2dsphere en el campo location.geo mediante el constructor Indexes:
collection.createIndex((Indexes.geo2dsphere("location.geo")))
Para obtener más información sobre el desarrollador Indexes, consulte el
Desarrolladores de índices guía.
Coordenadas en un plano 2D
Puedes almacenar datos geoespaciales utilizando las coordenadas x y y en un plano euclidiano bidimensional. Nos referimos a las coordenadas en un plano bidimensional como 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, debes agregar el campo que contiene los legacy coordinate pairs a un índice 2d. El siguiente fragmento crea un índice 2d en el campo coordinates utilizando el constructor Indexes:
collection.createIndex((Indexes.geo2d("coordinates")))
Para obtener más información sobre el constructor Indexes, consulte la guía Desarrolladores de índices.
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 constan de un operador de consulta y formas GeoJSON como parámetros de consulta.
Operadores del query
Para consultar sus datos geoespaciales, utilice uno de los siguientes operadores de consulta:
$near$geoWithin$nearSphere$geoIntersectsrequiere un índice 2dsphere
Puede especificar estos operadores de consulta en el controlador MongoDB Kotlin con los métodos de utilidad near(), geoWithin(), nearSphere() y geoIntersects() de la clase de generador 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 obtener más información sobre el generador Filters, consulta la guía de Generadores de filtro.
Parámetros de query
Para especificar una forma para usar en una query geoespacial, utiliza las clases Position, Point, LineString y Polygon del driver de Kotlin.
Para obtener más información sobre las clases de formas GeoJSON, consulte la documentación de la API del paquete GeoJSON.
Ejemplos de consultas geoespaciales
Los siguientes ejemplos utilizan el conjunto de datos de muestra de MongoDB Atlas. Puedes aprender a configurar tu propio clúster de Atlas de nivel gratuito y cómo cargar el conjunto de datos de muestra en la guía comenzar con el driver de Kotlin.
Los ejemplos utilizan la colección theaters en la base de datos sample_mflix del conjunto de datos de muestra.
Los ejemplos de esta sección requieren las siguientes importaciones:
import com.mongodb.client.model.geojson.Point import com.mongodb.client.model.geojson.Polygon import com.mongodb.client.model.geojson.Position import com.mongodb.client.model.Filters.near import com.mongodb.client.model.Filters.geoWithin import com.mongodb.client.model.Projections.fields import com.mongodb.client.model.Projections.include import com.mongodb.client.model.Projections.excludeId
Los documentos de muestra están modelados por la siguiente clase de datos de Kotlin:
data class Theater( val theaterId: Int, val location: Location ) { data class Location( val address: Address, val geo: Point ) { data class Address( val street1: String, val street2: String? = null, val city: String, val state: String, val zipcode: String ) } }
Los documentos resultantes son modelados por la siguiente clase de datos de Kotlin:
data class TheaterResults( val location: Location ) { data class Location( val address: Address ) { data class Address( val city: String ) } }
La colección theaters ya contiene un índice 2dsphere en el campo "${Theater::location.name}.${Theater.Location::geo.name}".
Query por Proximidad
Para buscar y devolver documentos desde el más cercano al más lejano a un punto, utiliza el método de utilidad estática near() de la clase constructora Filters. El método near() construye una consulta con el operador del query $near.
El siguiente ejemplo busca salas de cine ubicadas entre 10000 y 5000 metros del Gran Césped de Central Park:
val database = client.getDatabase("sample_mflix") val collection = database.getCollection<TheaterResults>("theaters") val centralPark = Point(Position(-73.9667, 40.78)) val query = Filters.near( "${Theater::location.name}.${Theater.Location::geo.name}", centralPark, 10000.0, 5000.0 ) val projection = Projections.fields( Projections.include( "${Theater::location.name}.${Theater.Location::address.name}.${Theater.Location.Address::city.name}"), Projections.excludeId() ) val resultsFlow = collection.find(query).projection(projection) resultsFlow.collect { println(it) }
TheaterResults(location=Location(address=Address(city=Bronx))) TheaterResults(location=Location(address=Address(city=New York))) TheaterResults(location=Location(address=Address(city=New York))) TheaterResults(location=Location(address=Address(city=Long Island City))) TheaterResults(location=Location(address=Address(city=New York))) TheaterResults(location=Location(address=Address(city=Secaucus))) TheaterResults(location=Location(address=Address(city=Jersey City))) TheaterResults(location=Location(address=Address(city=Elmhurst))) TheaterResults(location=Location(address=Address(city=Flushing))) TheaterResults(location=Location(address=Address(city=Flushing))) TheaterResults(location=Location(address=Address(city=Flushing))) TheaterResults(location=Location(address=Address(city=Elmhurst)))
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 utilitario static geoWithin() de la clase builder Filters. El método geoWithin() construye un query con el operador del query $geoWithin.
The following example searches for movie theaters in a section of Long Island.
val longIslandTriangle = Polygon( listOf( Position(-72.0, 40.0), Position(-74.0, 41.0), Position(-72.0, 39.0), Position(-72.0, 40.0) ) ) val projection = Projections.fields( Projections.include( "${Theater::location.name}.${Theater.Location::address.name}.${Theater.Location.Address::city.name}"), Projections.excludeId() ) val geoWithinComparison = Filters.geoWithin( "${Theater::location.name}.${Theater.Location::geo.name}", longIslandTriangle ) val resultsFlow = collection.find<TheaterResults>(geoWithinComparison) .projection(projection) resultsFlow.collect { println(it) }
TheaterResults(location=Location(address=Address(city=Baldwin)))) TheaterResults(location=Location(address=Address(city=Levittown))) TheaterResults(location=Location(address=Address(city=Westbury))) TheaterResults(location=Location(address=Address(city=Mount Vernon))) TheaterResults(location=Location(address=Address(city=Massapequa)))
La siguiente figura muestra el polígono definido por la variable longIslandTriangle y los puntos que representan las ubicaciones de las salas de cine devueltas por nuestra consulta.

Para obtener más información sobre el $geoWithin operador, consulte la referencia $geoWithin en el manual del servidor.