Search code examples
mongodbgeolocationgeospatial

How to get the records which contains the given location in its radius? Mongodb


My DB Mongoose schema looks like this.

var blogSchema = mongoose.Schema({
blogText: { type: String},
location: {type: [Number]},
radius : {type: Number},
});
blogSchema.index({location: 2dsphere});
 ... .. .. ...

Sample data looks like below

{ 
"_id" : 58ef3f1919f99e3bb37ce21b, 
"location" : [
    77.706106, 
    12.9447252
], 
"radius" : "4000",
"blogText" : "News 1 ....."},
{ 
"_id" : 58ef3f19b37ce21b19f99e3b, 
"location" : [
    77.709979, 
    12.9703882
], 
"radius" : "1000",
"blogText" : "Health 1 ....."},
{ 
"_id" : 58ef3f1919f99e3bb37ce21b, 
"location" :[
    77.7060119, 
    12.9488936
], 
"radius" : "3500",
"blogText" : "Lifestyle 1 ....."},
{ 
"_id" : 58ef3f1919f99e3bb37ce21b', 
"location" :  [
    77.709979, 
    12.9703882
], 
"radius" : "100",
"blogText" : "Sports....."},
{ 
"_id" : 58ef3f1919f99e3bb37ce21b', 
"location" : [
    77.706106, 
    12.9447252
], 
"radius" : "800",
"blogText" : "Tech ....."}

I have to fetch only those blogs which contains the user location under the blog location and radius.

My query looks like. Which fetch the data based on the location and radius of the request.

db.blogs.find({location: {$geoNear: {$geometry: {type: "Point",coordinates: [77.706106,12.9447252]}$maxDistance: 500,$minDistance: 0}}}} })

Thanks in Advance


Solution

  • Modified from this so answer, this might work for you.

    Use aggregate to push documents through a pipeline with three stages.

    1) $geoNear: find all documents near your desired coordinates, and return a generated distanceField called distance.

    2) $project: Use the $distance found in stage 1 and subtract from $radius, store as delta.

    3) $match: Filter out all delta less than or equal to zero.

    db.blogs.aggregate([
      {
        '$geoNear' : {
          near : [77.706106,12.9447252],
          distanceField : 'distance',
          includeLocs: 'location',
          spherical : true
        }
      }, 
      {
        '$project' : {
          name : 1,
          location : 1,
          delta : {
            '$subtract' : [
              '$radius', 
              '$distance'
            ]
          }
        }
      }, 
      {
        '$match' : {
          delta : { '$gte' : 0 }
        }
      }
    ])