Docs Menu
Docs Home
/ /

Buscar geoespacialmente

En esta guía, aprenderá a consultar datos geoespaciales con el controlador Kotlin. También podrá conocer los diferentes formatos de datos geoespaciales compatibles con 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 de ejercicio para perros en la ciudad de Nueva York

Para almacenar y consultar sus datos geoespaciales en MongoDB, utilice GeoJSON. GeoJSON es un formato de datos creado por el Grupo de Trabajo de Ingeniería de Internet (IETF).

Aquí está 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 especificación oficial del IETF.

Una posición representa un solo lugar en la Tierra y se proporciona como una matriz que contiene dos o tres valores numéricos:

  • Longitud en la primera posición (obligatorio)

  • Latitud en la segunda posición (obligatorio)

  • 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.

El tipo de un objeto GeoJSON determina su forma geométrica. Las formas geométricas se componen de posiciones.

A continuación se muestran algunos tipos GeoJSON comunes y cómo puedes especificarlos con posiciones:

  • PointPosición única. 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.

  • PolygonConjunto de posiciones donde la primera y la última coinciden, delimitando un espacio. Esto podría representar el terreno 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.

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 constructor Indexes, consulte Guíade creación de índices.

Puede almacenar datos geoespaciales utilizando x las y coordenadas y en un plano euclidiano bidimensional. Las coordenadas en un plano bidimensional se denominan pares de coordenadas heredadas.

Los pares de coordenadas heredados tienen la siguiente estructura:

{ "location" : [ x, y ] }

El valor del campo contiene una matriz de dos valores en la que el primero representa el valor del eje x y el segundo representa el valor del eje y.

Para consultar datos almacenados como pares de coordenadas heredados, debe agregar el campo que contiene dichos pares a un índice 2d. El siguiente fragmento crea un índice 2d en el campo coordinates mediante el constructor Indexes:

collection.createIndex((Indexes.geo2d("coordinates")))

Para obtener más información sobre el Indexes generador, consulte la guía Generadores de índices.

Para obtener más información sobre los pares de coordenadas heredados, consulte la sección Pares de coordenadas heredadas de la guía Consultas geoespaciales en el manual del servidor.

Tip

Operadores compatibles

Los índices esféricos () y planos2dsphere2d () admiten algunos, pero no todos, los mismos operadores de consulta. Para ver una lista completa de operadores y su compatibilidad con los índices, consulte la sección "Operadores de consulta geoespacial" de la guía "Consultas geoespaciales" del manual del servidor.

Las consultas geoespaciales constan de un operador de consulta y formas GeoJSON como parámetros de consulta.

Para consultar sus datos geoespaciales, utilice uno de los siguientes operadores de consulta:

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects requiere 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 de consultas geoespaciales, consulte la sección Operadores de consultas geoespaciales de la guía Consultas geoespaciales en el manual del servidor.

Para obtener más información sobre el Filters generador, consulte la guía Generadores de filtros.

Para especificar una forma para usar en una consulta geoespacial, utilice las clases Position, Point, LineString y Polygon del controlador Kotlin.

Para obtener más información sobre las clases de formas GeoJSON, consulte la documentación de la API del paquete GeoJSON.

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 de resultados están 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}".

Para buscar y devolver documentos desde el punto más cercano al más lejano, utilice el método de utilidad estática near() de la clase constructora Filters. El método near() construye una consulta con el operador de consulta $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 obtener más información sobre el $near operador, consulte la referencia $near en el manual del servidor.

Para buscar datos geoespaciales dentro de una forma específica, utilice el método de utilidad estática geoWithin() de la clase constructora Filters. El método geoWithin() construye una consulta con el operador de consulta $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.

Zona de Long Island donde buscar salas de cine

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

Volver

Limitar el número de resultados devueltos

En esta página