geospatial queries in mongodb location based data

Overview of Geospatial queries in MongoDB: Although we can perform the queries based on spatial coordinates in SQL as well the simplicity and ease of implementation of such queries in MongoDB which is a JSON based storage is quite easy. Let’s explore these by doing.

We will proceed with an example of collection named “Address”.

Geospatial Queries In MongoDB

The very first step to use queries based on Geospatial coordinates in MongoDB is to create a 2dsphere or 2d index for the field which holds the spatial data in GeoJSON or legacy coordinate pairs format.

Note: 2dsphere index is used for the spherical geometry(like earth) while 2d is used for a plan geometry.

let’s consider one document structure for the collection Address as:

 {

        "houseno": "",

        "street": "",

        "city": "",

        "country": ""

        "mapLocation": { type: "", coordinates: [-14.767834223.164836] } // For GeoJSON

        "mapLocation": [-14.7678342, 23.164836] // For legacy coordinate pairs

}

 Note*: For every coordinates field 1st element should be longitude and 2nd latitude. For example in the above document -14.7678342 is longitude & 23.164836 is latitude.

In the above document the if “mapLocation” field is in GeoJSON format then the type field

         May be one of these :

 1. Point: In this type, the coordinates field represent a single location. eg [34, 56]

2. MultiPoint: In this type, the coordinates field represent an array of locations

eg : [

         [-57.3562, 44.3421], 
         [-55.3572, 45.3491], 
         [-57.3862, 44.3121],
         [-56.3362, 43.3441]
        
      ]

 3. LineString:  In this type, the coordinates field represent an array of two or more locations (A Line)                          

 eg:  [ [-57.3562, 44.3421], [-56.3562, 42.3421] ]

 4. MultiLineString: In this type, the coordinates field represent an array of LineString coordinates  (Array of Lines).

 eg:  [

          [ [-57.3562, 44.3421], [-56.3562, 42.3421] ],
          [ [-57.3562, 44.3421], [-56.3562, 42.3421] ],
          [ [-57.3562, 44.3421], [-56.3562, 42.3421] ]
         
      ]

5. Polygon: In this type, the coordinates field represent an array of Linear rings (A closed loop made up of at least four LineStrings in which the first and last coordinates must be the same).

 eg : [ 
          [ 
             [0, 0], [3, 6], [6, 1], [0, 0] 
          ] 
      ]

 6. MultiPolygon: In this type, the coordinates field represent an array of Polygons.

 eg: [ 
         [ [ [-57.62, 44.21], [-57.32, 44.31], [-57.62, 44.3], [-57.35, 44.34] ] ],
         [ [ [-57.62, 44.21], [-57.32, 44.31], [-57.62, 44.3], [-57.35, 44.34] ] ], 
         [ [ [-57.62, 44.21], [-57.32, 44.31], [-57.62, 44.3], [-57.35, 44.34] ] ] 
     ]

Note*: For legacy coordinate pair, by default the “2dsphere” index converts the data in GeoJSON Point format

       Now, the index for mapLocation field can be created as :

db.Address.createIndex({"mapLocation": "2dsphere"}) // By mongodb command
AddressSchema.index({"mapLocation": "2dsphere"}) // By mongoose

For 2d index, just replace the index value by “2d” instead of “2dsphere”

All setup is done! Now let’s play with the various interesting queries using few operators provided by mongodb like $geoWithin, $near, $geoNear, $nearSphere, $geoIntersects

Also Read: Export HTML To PDF Using Javascript

Geospatial queries using MongoDB

 *We will consider only the “Point” type geometry having a single location in mapLocation field.

1. $geoWithin: With this operator, we can find locations(documents) those are within the specified shape like a box, polygon, circle, circle on a sphere(earth).

 Examples : 

   db.Address.find({
      "mapLocation": {
         $geoWithin: {
            $centerSphere: [ [-67.76458, 34.64573],  10/3963 ]
         }
      }
  })

The above query will return all the documents from the Address collection which exist within the circle having center [-67.76458, 34.64573] and 10 miles on spherical geometry. 3963 is in radians. $centerSphere supports both GeoJSON and legacy coordinate pairs for the data type of mapLocation and 2d and 2dsphere index both as well.

    db.Address.find({
       "mapLocation": {
          $geoWithin: {
             $box: {
                [ [bottom left coordinates], [top right coordinates] ]

              }
           }
        }
    })

You can Hire reactjs developers from here..!

For bottom left coordinates [0,0] and top right coordinates [20, 20] the above query will return all the documents from Address collection for which the mapLocation field exist within the box [0, 0], [0, 20], [20, 0], [20, 20]. $box operator only supported by legacy coor-dinates pairs and not with GeoJSON shapes.

    db.Address.find({
       "mapLocation": {
          $geoWithin: {
             $polygon: {
                [ [x1, y1], [x2, y2], [x3, y3] ]
             }
          }
       }
   })

The above query will return all the documents having coordinates within the polygon defined by [x1, y1], [x2, y2], [x3, y3]. $polygon operator only supports legacy coordinates pairs and not with GeoJSON shapes.

2. $nearSphere: With this operator, we can find all the documents having locations nearest to a given geometry. It calculates the distance using spherical geometry like earth.

Examples : 

     db.Address.find({
        "mapLocation": {
           $nearSphere: {
              $geometry: {
                 type: "Point",
                 coordinates: [-76.87635, 65.76363]
              },
              $minDistance: 500,
              $maxDistance: 1000
           }
        }
    })

The above query will return all the documents in sorted order from nearest to farthest from the spatial coordinate [-76.87635, 65.76363] having min distance 500 meters and max distance 1000 meters. And for legacy coordinate pairs on 2d index: 

       db.Address.find({
          "mapLocation": {
             $nearSphere: [-76.87635, 65.76363]
             $minDistance: 500,
             $maxDistance: 1000
          }
       })

Need React Js development services?

3. $near: With this operator, we can achieve the same result as from $nearSphere for “2dsphere” index but in case of “2d” $nearSphere still calculate the distance using spherical geometry while $near will use planar geometry to calculate the distance of mapLocation from the given coordinates.

   Examples :  

   Let's consider two documents in Address collection 
   db.Address.insert({"houseno": 1, 
                      "street": "Ring Road", 
                      "city": "Bangalore", 
                      "country": "IN", 
                      "mapLocation": [-0.22157, 51.507176]
                      })

   db.Address.insert({"houseno": 2, 
                      "street": "White Field", 
                      "city": "Bangalore", 
                      "country": "IN", 
                      "mapLocation": [-0.098092, 51.576198]
                      })

 Then for “2dsphere” index with GeoJSON query $nearSphere and $near both will return the same result but for “2d” index with legacy coordinate pairs result might be different.

      db.Address.find({
         $nearSphere: {$geometry: {type: "Point", coordinates:[-0.127748, 51.507333]}}
      }, "street") and 

      db.Address.find({
         $near: {$geometry: {type: "Point", coordinates: [-0.127748, 51.507333]}}
      }, "street")

Both the above queries will return the same result for “2dsphere” index

     Output : [{
       "street": "Ring Road"
     }, {
       "street": "White Field"
     }]

But if we apply “2d” index and legacy coordinate pair in below queries

     db.Address.find({
        "mapLocation": {"$nearSphere: [-0.127748, 51.507333]}
     }, "street") and 

 
     db.Address.find({
        "mapLocation": {$near: [-0.127748, 51.507333]}
     }, "street") 


     Output:[{
        "street": "White Field"
     }, {
        "street": "Ring Road"
     }]

4. $geoIntersects: With this operator, we can find all the documents from Address collection which intersects the specified geometry.

Examples : 

     db.Address.find({
        "mapLocation" : {
           $geoIntersects: {
              $geometry: {
                 type: "Polygon",
                 coordinates: [ [-13.6, 23.7], [-13.8, 23.9], [-13.5, 23.3], [-13.6, 23.7] ]
              }
           }
        }
    })

 The above query will return the documents whose spatial geometry intersects the geometry defined by [ [-13.6, 23.7], [-13.8, 23.9], [-13.5, 23.3], [-13.6, 23.7] ]. Only “2dsphere” index supports the $geoIntersects

Need Node.Js development Services?

Summary
Article Name
Geospatial Queries In MongoDB(Using location based data)
Description
The very first step to use queries based on Geospatial coordinates in MongoDB is to create a 2dsphere or 2d index for the field which holds the spatial data
Author
Publisher Name
CronJ
Publisher Logo

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.