¡Hasta -30% en todos los libros en línea,
eformaciones y vídeos*! Código: NEURONA30 Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros y videos
  2. MongoDB
  3. Consultas geoespaciales
Extrait - MongoDB Comprensión y optimización de la gestión de datos (con ejercicios y soluciones)
Extractos del libro
MongoDB Comprensión y optimización de la gestión de datos (con ejercicios y soluciones) Volver a la página de compra del libro

Consultas geoespaciales

Introducción

Sabemos ahora que conviene utilizar los objetos GeoJSON para consultas geoespaciales. He aquí una colección de ejemplo llamada Aviñon, que enumera algunos de los monumentos importantes y lugares notables de la antigua ciudad papal. Todos estos lugares están representados en forma de objetos GeoJSON de tipo Point:

db.aviñon.insertMany([{  
   "nombre": "Palacio Papal",  
   "localización": {  
       "coordinates": [43.9507, 4.8075],  
       "type": "Point"  
   }  
},  
{  
   "nombre": "Puente San-Bénézetzet",  
   "localización": {  
       "coordinates": [43.95397, 4.80478],  
       "type": "Point"  
   }  
},  
{  
   "nombre": "Colección Lambert",  
   "localización": {  
       "coordinates": [43.944787, 4.804031],  
       "type": "Point"...

El operador $nearSphere

Este operador requiere un índice geoespacial 2dsphere cuando se utiliza con objetos GeoJSON y un índice 2d cuando se utiliza con coordenadas legacy. Cuando opera con objetos GeoJSON de tipo Punto, su sintaxis es:

{  
$nearSphere: {  
    $geometría: {  
       type : "Point",  
       coordinates : [ <longitud>, <latitud> ]  
    },  
    $minDistance: <distancia en metros>,  
    $maxDistance: <distancia en metros>  
}  
} 

Los campos $minDistance y $maxDistance son opcionales y se miden en metros.

Cuando se trabaja con coordenadas heredadas, el operador tiene esta forma:

{  
 $nearSphere: [ <x>, <y> ],  
 $minDistance: <distancia en radianes>,  
 $maxDistance: <distancia en radianes>.  
} 

Los campos $minDistance y $maxDistance también son opcionales, pero su unidad de medida es el radián en lugar del metro. Ya lo hemos mencionado, pero hay que recordar que cuando x e y representan coordenadas geográficas, siempre se debe especificar primero la longitud.

Tanto si se trabaja con objetos GeoJSON como con coordenadas legacy, $nearSphere devuelve los documentos ordenados en orden ascendente de distancia desde el punto que representa el centro de la búsqueda. Es posible ordenarlos de otra manera realizando una ordenación que anulará la ordenación realizada de forma interna por $nearSphere pero, para evitar sobrescribir esta preordenación, es preferible utilizar el operador $geoNear, que no realiza ninguna ordenación.

Vamos a ejecutar dos consultas para utilizar $nearSphere en su versión «simplificada», es decir, sin ninguno de los campos opcionales.

Nuestro punto central será la Ópera de Aviñón. Como estamos trabajando con el intérprete JavaScript en la línea de comandos, aprovecharemos para almacenar este objeto en un archivo:

var opera = { type : "Point", coordinates : [ 43.949749, 4.805325 ]} 

En un plano...

El operador $geoWithin

Este operador permite capturar documentos cuyos datos geoespaciales residan íntegramente en una forma definida en forma de objetos GeoJSON que encarnen un polígono o multipolígono (denominados Polygon y Multipolygon respectivamente) o una forma definida por coordenadas legacy.

A diferencia de $nearSphere, el operador $geoWithin no realiza ninguna preclasificación antes de la visualización y no requiere ninguna indexación geoespacial, aunque se recomienda utilizar un índice 2dsphere o 2d para optimizar el rendimiento de la consulta.

MongoDB utiliza su propio Sistema de Coordenadas de Referencia (RCS) para las áreas representadas por formas cuya superficie es igual o superior al tamaño de un hemisferio.

Empecemos por crear un polígono que excluya uno de los tres documentos simbolizados por un marcador naranja en nuestro mapa.

images/cap04-img02.png

Almacenaremos sus coordenadas en una variable JavaScript llamada polygon antes de usarla en nuestra primera consulta usando $geoWithin. Esta consulta operará sobre la colección aviñon2d pasando nuestro polígono como parámetro. En primer lugar, veamos la sintaxis de nuestro operador cuando trabajamos con coordenadas heredadas sobre una superficie plana:

{  
     <campo de documentos que contiene las coordenadas>: {  
            $geoWithin: {  
                   <operador de forma >: <coordenadas > 
            }  
     }  
} 

El campo que contiene las coordenadas en nuestros documentos no ha cambiado, nuestro operador de forma será $polygon y las coordenadas estarán contenidas en una matriz de pares longitud/latitud que se muestra a continuación:

var polígono = [  
     [43.9548, 4.80143],  
     [43.95475, 4.80779],  
     [43.95045, 4.81097],  
     [43.94657, 4.80449]  
] 

La consulta que utiliza el polígono dibujado en nuestro mapa y cuyos distintos puntos están en la variable polígono...

El operador $geoIntersects

Este operador selecciona los documentos en los que la intersección de datos geoespaciales con objetos GeoJSON no está vacía. Su sintaxis es la siguiente:

{  
     <campo de documentos que contienen coordenadas>: {  
           $geoIntersects: {  
               $geometry: {  
                   "type": < Cualquier tipo de objeto GeoJSON> ,  
                   "coordinates": [ < coordenadas > ]  
               }  
           }  
     }  
} 

Para utilizar el operador $geoIntersects, vamos a crear intersecciones de polígonos a nivel del polígono llamado polígono2. Este es el aspecto que tendrá nuestro mapa actualizado de Aviñón:

images/cap04-img04.png

Nuestro polígono original está a la izquierda, y le hemos añadido dos triángulos:

  • un triángulo en el centro, que llamaremos...