Tuesday, August 7, 2018

Mongodb get document in nearby order from current coordinates using mongoose

By using $near mongodb operator, you can find documents/records from your nearest to far order.
This is most useful to find nearby restaurants, friends, petrol pumps, etc.

here, we will make a demo  to find nearest restaurant

Ex: mongoose schema (restaurant.js)
var mongoose = require('mongoose'),
        Schema = mongoose.Schema;

var restaurantSchema = new Schema({
    restaurant_logo: {
        type: String,
    },
    restaurant_name: {
        type: String,
        index: true
    },
    email: {
        type: String, // Unique Email for sign up
        unique: true,
    },
    password: {
        type: String, // Password
    },
    salt: {
        type: String,
    },
    is_active: {
        type: Number, // -1: pending to activation, 0: inactive, 1: active
        default: -1
    },
    created_at: {
        type: Date,
        default: Date.now
    }, // Registration date
    updated_at: {
        type: Date,
        default: Date.now
    },
    //Start more for restaurant field
    address: {
        type: String,
    },
    country: {
        type: String,
    },
    city: {
        type: String,
    },
    location: { //latitude,longigude information
     type: { type: String, default : "Point" },
     coordinates: []
    }
}, {collection: 'restaurant'});

/**
*Creating Indexs
*/
restaurantSchema.index({ location: "2dsphere" }); // for get near by location using $near

/**
 *Validations
 */
restaurantSchema.path('restaurant_name').required(true, 'restaurant name is required.');
restaurantSchema.path('email').required(true, 'email is required.');
//restaurantSchema.path('password').required(true, 'password is required.');
restaurantSchema.path('salt').required(true, 'salt is required.');

/*
 *Define model and export it for use in other page
 */
var Restaurant = module.exports = mongoose.model("Restaurant", restaurantSchema);
module.exports = Restaurant;

In the above model schema, we have take location field for location type and coordinates of latitude and longitude.

you need to use the GeoJSON format if your data is in GeoJSON format, that's why we take location field in GeoJSON format.

for location field, we have to create an index as "2dsphere".

$near requires a geospatial / two-way index as per below conditions:

1) if specifying a GeoJSON point, 2dsphere index
2) if specifying a point using legacy coordinates, 2d index.

To specify a GeoJSON point, $near operator requires a 2dsphere index, so without 2dsphere we cannot use $near operator to get documents/records from your nearest to far order.

Imp Note :
Valid latitude values are between -90 and 90 (both inclusive).
Valid longitude values are between -180 and 180 (both inclusive).

after creating this mongoose model enter data to get document/ record like as below format.
 db.temp.find({},{restaurant_logo : 1, restaurant_name : 1, email : 1, address : 1, country : 1, city : 1, location : 1}).pretty()
{
    "_id" : ObjectId("5b6419f28f792b4f630d2f29"),
    restaurant_logo: "15215421212.png",
    restaurant_name: "restaurant 1",
    email: "restaurant1@gmail.com",
    address: "bopal, ahmedabad",
    country: "India",
    city: "Ahmedabad",
    "location" : {
        "type" : "Point",
        "coordinates" : [
            23.033677,
            72.463412
        ]
    }
}
{
    "_id" : ObjectId("5b641a2903e5ee4fbcd7597a"),
    restaurant_logo: "1521542452.png",
    restaurant_name: "restaurant 2",
    email: "restaurant2@gmail.com",
    "address" : "chandlodiya, ahmedabad",
    country: "India",
    city: "Ahmedabad",
    "location" : {
        "type" : "Point",
        "coordinates" : [
            23.08754,
            72.550473
        ]
    }
}
{
    "_id" : ObjectId("5b641a7e9d783f507b1c9475"),
    restaurant_logo: "152154222452.png",
    restaurant_name: "restaurant 3",
    email: "restaurant3@gmail.com",
    "address" : "kalawad road",
    country: "India",
    city : "Rajkot",
    "location" : {
        "type" : "Point",
        "coordinates" : [
            22.303894,
            70.80216
        ]
    },
    "__v" : 0
}

restaurant.js (API)
var  express = require('express');
var  router = express.Router();
var Restaurant = require('../models/restaurant');

router
                .route("/api/restaurant/get")
                .get(function(req, res) {
               
                    Restaurant.find({
                        location: {
                         $near: {
                          //$maxDistance: 1000,
                          $geometry: {
                           type: "Point",
                           coordinates: [23.08754,72.550473]
                          }
                         }
                        }
                       },function(error, results){
                        if (error) console.log(error);
                        console.log(JSON.stringify(results, 0, 2));
                       });
                });

module.exports = router;

By using $near and $geometry operator you can get the document as per your expected result.

Here you can use $maxDistance operator for getting only in given distance.

here, I have put coordinates (latitude, longitude) static in query of restaurant.js (API), but you can pass dynamic of user's current location's coordinates (latitude, longitude) by using any API like as Google Geocoder API in front-end side.

No comments:

Post a Comment