Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /

Buscar geoespacialmente

En esta guía, puedes aprender cómo buscar datos geoespaciales con MongoDB Java Driver, y 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. 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

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:

"MongoDB Headquarters" : {
"type": "point",
"coordinates": [-73.986805, 40.7620853]
}

Para obtener información definitiva sobre GeoJSON, consulte el especificación oficial de IETF.

Una posición representa un único lugar en la Tierra y existe en el código 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 longitud primero y latitud después. Esto puede ser sorprendente, ya que las convenciones de los sistemas de coordenadas geográficas suelen listar primero la latitud y luego la longitud. Asegúrate de comprobar qué formato utilizan las demás herramientas con las que trabajas. Herramientas populares como OpenStreetMap y Google Maps enumeran las coordenadas como latitud primero y longitud después.

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:

  • Point: una única posición. Esto puede representar la ubicación de una escultura.

  • LineString: un arreglo de dos o más posiciones, formando así una serie de segmentos de línea. Esto puede representar la ruta de la Gran Muralla China.

  • Polygon: un arreglo de posiciones en la que la primera y la última posición son iguales, por lo que se encierra un espacio. Esto puede representar la tierra dentro de la Ciudad del Vaticano.

Para aprender más sobre las figuras que puedes utilizar en MongoDB, consulta la entrada del manual de GeoJSON.

Para insertar un documento que almacene datos GeoJSON, crea un documento que contenga un valor GeoJSON y pasa el documento al método insertOne().

El siguiente ejemplo inserta un documento que incluye un campo location.geo, el cual contiene datos GeoJSON:

// Add your MongoCollection setup code here
Point point = new Point(new Position(-74.0065, 40.7085));
Document theater = new Document("theaterId", 1203)
.append("location", new Document("geo", point));
InsertOneResult result = collection.insertOne(theater);

Para obtener más información sobre cómo insertar documentos, consulte la Guía de operaciones de inserción.

Para query datos almacenados en el formato GeoJSON, agregue el campo que contiene datos GeoJSON a un índice 2dsphere. El siguiente snippet crea un índice 2dsphere en el campo location.geo usando el builder Indexes:

// <MongoCollection setup code here>
collection.createIndex(Indexes.geo2dsphere("location.geo"));

Para más información sobre el constructor de Indexes, consulta nuestra guía sobre el constructor de Índices.

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:

"<field name>" : [ x, y ]

El campo debe contener un arreglo de dos valores, en el que el primero representa el valor del eje x y el segundo representa el valor del eje y.

Para insertar un documento que almacene un par de coordenadas heredado, se debe crear un documento que asigne un valor de par de coordenadas a un campo. Luego, pase el documento al método insertOne().

El siguiente ejemplo inserta un documento que incluye un campo coordinates, el cual contiene un par de coordenadas heredadas:

// Add your MongoCollection setup code here
Document theater = new Document("theaterId", 1204)
.append("coordinates", Arrays.asList(-73.9862, 40.7311));
InsertOneResult result = collection.insertOne(theater);

Para obtener más información sobre cómo insertar documentos, consulte la guía de Operaciones de inserción.

Para query datos almacenados como legacy coordinate pairs, debe 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 generador Indexes:

// <MongoCollection setup code here>
collection.createIndex(Indexes.geo2d("coordinates"));

Para más información sobre el constructor de Indexes, consulta nuestra guía sobre el constructor de Índices.

Para obtener más información sobre pares de coordenadas antiguos, consulta la página de manual de MongoDB Server sobre pares de coordenadas antiguos.

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 el índice, consulta la entrada del manual de consultas geoespaciales.

Las consultas geoespaciales consisten en un operador del query y formas GeoJSON como parámetros del query.

Para query tus datos geoespaciales, utiliza uno de los siguientes operadores del query:

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects requiere un índice 2dsphere

Puedes especificar estos operadores del query en el driver Java de MongoDB con los métodos utilitarios near(), geoWithin(), nearSphere() y geoIntersects() de la clase de desarrolladores Filters.

Para obtener más información sobre los operadores del query geoespacial, consulta la entrada del manual sobre queries geoespaciales.

Para obtener más información sobre Filters, consulta nuestra guía sobre el constructor de filtros.

Para especificar una forma a utilizar en una query geoespacial, utiliza las clases Position, Point, LineString y Polygon del driver Java de MongoDB.

Para obtener una lista completa de las formas GeoJSON disponibles en el driver de Java de MongoDB, consulta la paquete de GeoJSON Documentación de API.

Los siguientes ejemplos utilizan el conjunto de datos de muestra de MongoDB Atlas. Puedes aprender cómo configurar tu propio clúster Atlas de nivel gratuito y cómo cargar el conjunto de datos de muestra en nuestra guía de inicio rápido.

Los ejemplos utilizan la colección theaters en la base de datos sample_mflix del conjunto de datos de muestra. La colección theaters contiene un índice 2dsphere en el campo location.geo.

Los ejemplos requieren las siguientes importaciones:

import java.util.Arrays;
import org.bson.conversions.Bson;
import com.mongodb.client.model.geojson.Point;
import com.mongodb.client.model.geojson.Polygon;
import com.mongodb.client.model.geojson.Position;
import static com.mongodb.client.model.Filters.near;
import static com.mongodb.client.model.Filters.geoWithin;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;
import static com.mongodb.client.model.Projections.excludeId;

Puedes encontrar el código fuente de los ejemplos en Github aquí.

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 teatros entre 10,000 y 5,000 metros del Gran césped de Central Park.

// Add your MongoClient setup code here
MongoDatabase database = mongoClient.getDatabase("sample_mflix");
MongoCollection<Document> collection = database.getCollection("theaters");
Point centralPark = new Point(new Position(-73.9667, 40.78));
// Creates a query that matches all locations between 5,000 and 10,000 meters from the specified Point
Bson query = near("location.geo", centralPark, 10000.0, 5000.0);
// Creates a projection to include only the "location.address.city" field in the results
Bson projection = fields(include("location.address.city"), excludeId());
// Prints the projected field of the results from the geospatial query as JSON
collection.find(query)
.projection(projection)
.forEach(doc -> System.out.println(doc.toJson()));

El resultado del código anterior se asemeja al siguiente:

{"location": {"address": {"city": "Bronx"}}}
{"location": {"address": {"city": "New York"}}}
{"location": {"address": {"city": "New York"}}}
{"location": {"address": {"city": "Long Island City"}}}
{"location": {"address": {"city": "New York"}}}
{"location": {"address": {"city": "Secaucus"}}}
{"location": {"address": {"city": "Jersey City"}}}
{"location": {"address": {"city": "Elmhurst"}}}
{"location": {"address": {"city": "Flushing"}}}
{"location": {"address": {"city": "Flushing"}}}
{"location": {"address": {"city": "Flushing"}}}
{"location": {"address": {"city": "Elmhurst"}}}

Tip

Dato curioso

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 operador $near, consulte la documentación de referencia de $near.

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

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.

// Add your MongoCollection setup code here
// Creates a set of points that defines the bounds of a geospatial shape
Polygon longIslandTriangle = new Polygon(Arrays.asList(new Position(-72, 40),
new Position(-74, 41),
new Position(-72, 39),
new Position(-72, 40)));
// Creates a projection to include only the "location.address.city" field in the results
Bson projection = fields(include("location.address.city"), excludeId());
// Creates a query that matches documents containing "location.geo" values within the specified bounds
Bson geoWithinComparison = geoWithin("location.geo", longIslandTriangle);
// Prints the projected field of the results from the geolocation query as JSON
collection.find(geoWithinComparison)
.projection(projection)
.forEach(doc -> System.out.println(doc.toJson()));

El resultado del código anterior se asemeja al siguiente:

{"location": {"address": {"city": "Baldwin"}}}
{"location": {"address": {"city": "Levittown"}}}
{"location": {"address": {"city": "Westbury"}}}
{"location": {"address": {"city": "Mount Vernon"}}}
{"location": {"address": {"city": "Massapequa"}}}

La figura siguiente muestra el polígono definido por la variable longIslandTriangle y puntos que representan las ubicaciones de los cines que arrojó nuestra query.

Zona de Long Island donde estamos buscando cines.

Para obtener más información sobre el operador $geoWithin, consulte la documentación de referencia para $geoWithin

Para obtener más información sobre los operadores que puedes utilizar en tu query, consulta la página del manual de MongoDB Server sobre operadores de consultas geoespaciales

Volver

Omitir resultados devueltos

En esta página