Consultas geoespaciales con DocumentDB

A día de hoy es muy importante saber qué es lo que tienes alrededor. Es por ello que la geolocalización supone un reto que muchas aplicaciones necesitan saber gestionar correctamente. Hoy te quiero contar cómo puedes realizar consultas geoespaciales con DocumentDB de una forma sencilla, utilizando el protocolo de MongoDB para que sea compatible con dicha base de datos y poder hacer uso de librerías que posiblemente ya conozcas.

Lo primero que debes saber es cómo tienes que guardar las coordenadas de aquellos sitios que vas a querer consultar después.

dbdoc.collection("Places").insertOne({
                                    "name": result.name,
                                    "address": result.address,                                    
                                    "phone": result.phone,                                    
                                    "location": {
                                        "type": "Point",
                                        "coordinates": result.geometry.location.lng, coords[0].geometry.location.lat]
                                    }, (err, item) => {
                                        if (err)
                                            console.error(err);
                                        else
                                            console.log(item);
                                    });

Utilizando el módulo mongodb, como ya te conté en este otro post, puedes insertar entidades en DocumentDB como si de un MongoDB se tratara. Para poder hacer consultas geoespaciales debes guardar las coordenadas en una propiedad del tipo Point y guardar en coordinates la longitud y la latitud en forma de array.

Una vez almacenados todos los valores en la colección ya podrás hacer consultas de la misma forma que las harías en un MongoDB. Por ejemplo:

module.exports.nearPlaces = (coords, name, radio, done) => {
    mongodb.connect(url, function (err, docdb) {
        let regexValue = new RegExp("^" + name.toLowerCase().substr(0, 5), "i");
        
        if (err) {
            console.error('error!', err);
        }
        else {
            docdb.collection("Places").find({
                "location": {
                    $near: {
                        $geometry: {
                            type: "Point",                            
                            coordinates: [coords.longitude, coords.latitude]
                        },
                        $maxDistance: radio
                    }
                },                
                "name": { $regex: regexValue }
            }).toArray((err, docs) => {
                if (err) {
                    console.log("error", err);
                }
                else {
                    done(docs);
                }
            });

        }
    });
};

En este ejemplo lo que estoy buscando son todos aquellos lugares que estén cerca de las coordenadas pasadas como parámetro y que además el nombre del sitio coincida con las 5 primeras letras, utilizando una expresión regular, en un radio expresado en metros, también pasado como parámetro. Esto me devolverá un array con todos aquellos lugares, insertados previamente en la colección, que cumplan con ese radio de distancia y ese nombre, usando las coordenadas pasadas como punto de referencia.

En esta parte de la documentación de MongoDB puedes revisar todos los operadores disponibles, para hacer consultas en base a las coordenadas que tienes almacenadas en tu DocumentDB.

¡Saludos!