Docs Menu
Docs Home
/ /

Encuentre restaurantes con consultas geoespaciales

MongoDB La indexacióngeoespacial permite ejecutar consultas espaciales de forma eficiente en una colección que contiene formas y puntos geoespaciales. Para mostrar las capacidades de las entidades geoespaciales y comparar diferentes enfoques, este tutorial le guiará en el proceso de creación de consultas para una aplicación geoespacial sencilla.

Este tutorial presentará brevemente los conceptos de índices geoespaciales y luego demostrará su uso con $geoWithin$geoIntersects,$nearSphere y.

Supongamos que está diseñando una aplicación móvil para ayudar a los usuarios a encontrar restaurantes en la ciudad de Nueva York. La aplicación debe:

  • Determinar el vecindario actual del usuario $geoIntersects usando,

  • Muestra el número de restaurantes en ese vecindario usando,$geoWithin y

  • Encuentre restaurantes dentro de una distancia específica del usuario $nearSphere usando.

Este tutorial utilizará un índice 2dsphere para consultar estos datos sobre geometría esférica.

Para obtener más información sobre geometrías esféricas y planas, consulte Modelos geoespaciales.

La geometría esférica parecerá distorsionada cuando se visualiza en un mapa debido a la naturaleza de proyectar una esfera tridimensional, como la tierra, sobre un plano plano.

Por ejemplo, tomemos la especificación del cuadrado esférico definido por los puntos de longitud y latitud (0,0), (80,0), (80,80) y (0,80). La siguiente figura representa el área que abarca esta región:

Diagrama de un cuadrado proyectado sobre una esfera.
haga clic para ampliar

Descargue los conjuntos de datos de ejemplo desde https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/neighborhoods.jsony https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/restaurants.json. Estos contienen las colecciones restaurants y neighborhoods respectivamente.

Después de descargar los conjuntos de datos, impórtalos en la base de datos:

mongoimport <path to restaurants.json> -c=restaurants
mongoimport <path to neighborhoods.json> -c=neighborhoods

Un índice geoespacial que casi siempre mejora el rendimiento de las consultas $geoWithin $geoIntersects y.

Dado que estos datos son geográficos, cree un 2dsphere índice en cada colección mongosh utilizando:

db.restaurants.createIndex({ location: "2dsphere" })
db.neighborhoods.createIndex({ geometry: "2dsphere" })

Inspeccionar una entrada en la restaurants colección recién mongosh creada en:

db.restaurants.findOne()

Esta consulta devuelve un documento como el siguiente:

{
location: {
type: "Point",
coordinates: [-73.856077, 40.848447]
},
name: "Morris Park Bake Shop"
}

Este documento de restaurante corresponde a la ubicación que se muestra en la siguiente figura:

Mapa de un solo punto geoespacial.

Debido a que el tutorial utiliza un 2dsphere índice, los datos de geometría en el location campo deben seguir el formato GeoJSON.

Ahora inspeccione una entrada en la colección neighborhoods:

db.neighborhoods.findOne()

Esta consulta devolverá un documento como el siguiente:

{
geometry: {
type: "Polygon",
coordinates: [[
[ -73.99, 40.75 ],
...
[ -73.98, 40.76 ],
[ -73.99, 40.75 ]
]]
},
name: "Hell's Kitchen"
}

Esta geometría corresponde a la región representada en la siguiente figura:

Mapa de un polígono geoespacial.
haga clic para ampliar

Suponiendo que el dispositivo móvil del usuario puede proporcionar una ubicación razonablemente precisa del usuario, es sencillo encontrar el vecindario actual del usuario $geoIntersects con.

Supongamos que el usuario se encuentra en - de73.93414657 longitud y de 40.82302903 latitud. Para encontrar el vecindario actual, especifique un punto usando el $geometry campo especial en formato GeoJSON:

db.neighborhoods.findOne({ geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] } } } })

Esta consulta devolverá el siguiente resultado:

{
"_id" : ObjectId("55cb9c666c522cafdb053a68"),
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[
-73.93383000695911,
40.81949109558767
],
...
]
]
},
"name" : "Central Harlem North-Polo Grounds"
}

También puedes consultar para encontrar todos los restaurantes de un barrio determinado. Ejecuta lo siguiente en mongosh para encontrar el barrio que contiene al usuario y luego cuenta los restaurantes dentro de él:

var neighborhood = db.neighborhoods.findOne( { geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] } } } } )
db.restaurants.find( { location: { $geoWithin: { $geometry: neighborhood.geometry } } } ).count()

Esta consulta le dirá que hay 127 restaurantes en el barrio solicitado, visualizados en la siguiente figura:

Mapa de todos los restaurantes en un polígono geoespacial.
haga clic para ampliar

Para encontrar restaurantes dentro de una distancia específica de un punto, puedes usar $geoWithin con $centerSphere para devolver resultados en un orden no ordenado, o $nearSphere con $maxDistance si necesitas resultados ordenados por distancia.

Para encontrar restaurantes dentro de una región circular, utilice $geoWithin $centerSpherecon. es una sintaxis específica de MongoDB para denotar una región circular especificando el centro y el radio en$centerSphere radianes.

$geoWithin no devuelve los documentos en ningún orden específico, por lo que puede mostrar al usuario los documentos más alejados primero.

Lo siguiente encontrará todos los restaurantes dentro de un radio de cinco millas del usuario:

db.restaurants.find({ location:
{ $geoWithin:
{ $centerSphere: [ [ -73.93414657, 40.82302903 ], 5 / 3963.2 ] } } })

$centerSphereEl segundo argumento de acepta el radio en radianes, por lo que debe dividirlo entre el radio de la Tierra en millas.Consulte Convertir distancia a radianes para operadores esféricos para obtener más información sobre la conversión entre unidades de distancia.

También puede usar $nearSphere y especificar un término de $maxDistance en metros. Esto devolverá todos los restaurantes dentro de cinco millas del usuario en orden ordenado desde el más cercano al más lejano:

var METERS_PER_MILE = 1609.34
db.restaurants.find({ location: { $nearSphere: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] }, $maxDistance: 5 * METERS_PER_MILE } } })

Volver

Query geoespacial

En esta página