Cara menggunakan geospatial index mongodb

Hey sob, pada tutorial kali ini saya ingin membahas geospasial query menggunakan database mongodb. Apa itu geospasial query sederhananya itu digunakan untuk mengukur jarak menggunakan latitude dan longitude dari 2 titik. Tujuannya dapat mengukur atau mencari tempat terdekat dengan radius tertentu.

Kemudian pertanyaannya kenapa mongodb? Oke saya jelaskan alasan kenapa saya pilih awalnya karena saya familiar dengan mongodb hehehe.. dan karena di mongodb ada beberapa index geospasial yang bisa kita gunakan tanpa harus kita buat perhitungan yang rumit. Di mongodb ada yang namanya index 2dsphere.

{

loc : { type: "Point", coordinates: [ yourlongitude, yourlatitude ] }

}

Oke langsung saja kita coba.

Pertama saya asumsikan kita sudah punya sebuat projek laravel. masuk ke root direktory laravel kemudian kita install library dari https://github.com/jenssegers/laravel-mongodb

Pertama-tama buat dulu model seperti ini.

Selanjutnya simpan data beserta dengan latitude dan longitude dengan format seperti yang sudah saya sampaikan di atas.

TextSearchModel::raw()->createIndex([‘loc’ => ‘2dsphere’]);

Kode diatas digunakan untuk membuat index 2dsphere, jangan lupa menambahkan kode tersebut setelah insert data lokasi anda.

Selanjutnya jika sudah berhasil disimpan maka untuk mendapatkan lokasi terdekat. Maka kodenya seperti ini.

TextSearchModel::where(‘loc’, ‘near’, [ ‘$geometry’ => [‘type’ => ‘Point’,’coordinates’ => [(float)$longitude,(float)$latitude]], ‘$maxDistance’ => (float)env(“PLACE_SEARCH_RADIUS”,150000)])

With the command, a collection can have only one

{ "_id" : ObjectId(" ... "), "loc" : [ -73, 39 ] }
2 index. With such as operator, a collection can have multiple geospatial indexes.

Proximity Queries

Proximity queries select the documents closest to the point specified in the query. To perform proximity queries you use either the method with the operator or you use the command.

The method with the operator returns 100 documents by default and sorts the results by distance. The operator uses the following form:

copy

db.collection.find( { <location field>: { $near: [ x, y ] } } )

Example

The following query

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )

returns output similar to the following:

copy

{ "_id" : ObjectId(" ... "), "loc" : [ -73, 39 ] }

The command returns more information than does the operator. The command can only return a single 16-megabyte result set. The command also offers additional operators, such as operators to query for or distance. For a list of operators, see .

Without additional operators, the command uses the following form:

copy

db.runCommand( { geoNear: <collection>, near: [ x, y ] } )

Example

The following command returns the same results as the in the previous example but with more information:

copy

db.runCommand( { geoNear: "places", near: [ -74, 40.74 ] } )

This operation will return the following output:

copy

{
   "ns" : "test.places",
   "results" : [
      {
         "dis" : 3,
         "obj" : {
            "_id" : ObjectId(" ... "),
            "loc" : [
               -73,
               39
            ]
         }
      }
   ],
   "stats" : {
      "time" : 2,
      "btreelocs" : 0,
      "nscanned" : 1,
      "objectsLoaded" : 1,
      "avgDistance" : 3,
      "maxDistance" : 3.0000188685220253
   },
   "near" : "0110000111111000000111111000000111111000000111111000",
   "ok" : 1
}

Distance Queries

You can limit a proximity query to those documents that fall within a maximum distance of a point. You specify the maximum distance using the units specified by the coordinate system. For example, if the coordinate system uses meters, you specify maximum distance in meters.

To specify distance using the method, use operator. Use the following form:

copy

db.collection.find( { <location field> : { $near : [ x , y ] , $maxDistance : <distance> } } )

To specify distance with the command, use the

db.runCommand( { geoNear: "places", near: [ -74, 40.74 ] } )
4 option. Use the following form:

copy

db.runCommand( { geoNear: <collection>, near: [ x, y ], maxDistance: <distance> } )

Limit the Number of Results

By default, geospatial queries using method return 100 documents, sorted by distance. To limit the result when using the method, use the method, as in the following prototype:

copy

db.collection.find( { <location field>: { $near: [ x, y ] } } ).limit(<n>)

To limit the result set when using the command, use the

db.runCommand( { geoNear: "places", near: [ -74, 40.74 ] } )
9 option. Use the following form:

copy

db.runCommand( { geoNear: <collection>, near: [ x, y ], num: z } )

To limit geospatial search results by distance, see .

Bounded Queries

Bounded queries return documents within a shape defined using the operator. MongoDB’s bounded queries support the following shapes:

Bounded queries do not return sorted results. As a result MongoDB can return bounded queries more quickly than . Bounded queries have the following form:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
0

The following sections describe each of the shapes supported by bounded queries:

Circles

To query for documents with coordinates inside the bounds of a circle, specify the center and the radius of the circle using the operator and option. Consider the following prototype query:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
1

The following example query returns all documents that have coordinates that exist within the circle centered on

{
   "ns" : "test.places",
   "results" : [
      {
         "dis" : 3,
         "obj" : {
            "_id" : ObjectId(" ... "),
            "loc" : [
               -73,
               39
            ]
         }
      }
   ],
   "stats" : {
      "time" : 2,
      "btreelocs" : 0,
      "nscanned" : 1,
      "objectsLoaded" : 1,
      "avgDistance" : 3,
      "maxDistance" : 3.0000188685220253
   },
   "near" : "0110000111111000000111111000000111111000000111111000",
   "ok" : 1
}
3 and with a radius of
{
   "ns" : "test.places",
   "results" : [
      {
         "dis" : 3,
         "obj" : {
            "_id" : ObjectId(" ... "),
            "loc" : [
               -73,
               39
            ]
         }
      }
   ],
   "stats" : {
      "time" : 2,
      "btreelocs" : 0,
      "nscanned" : 1,
      "objectsLoaded" : 1,
      "avgDistance" : 3,
      "maxDistance" : 3.0000188685220253
   },
   "near" : "0110000111111000000111111000000111111000000111111000",
   "ok" : 1
}
4, using a geospatial index on the
{
   "ns" : "test.places",
   "results" : [
      {
         "dis" : 3,
         "obj" : {
            "_id" : ObjectId(" ... "),
            "loc" : [
               -73,
               39
            ]
         }
      }
   ],
   "stats" : {
      "time" : 2,
      "btreelocs" : 0,
      "nscanned" : 1,
      "objectsLoaded" : 1,
      "avgDistance" : 3,
      "maxDistance" : 3.0000188685220253
   },
   "near" : "0110000111111000000111111000000111111000000111111000",
   "ok" : 1
}
5 field:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
2

The operator using is similar to using , but has different performance characteristics. MongoDB does not sort queries that use the operator are not sorted, unlike queries using the operator.

Rectangles

To query for documents with coordinates inside the bounds of a rectangle, specify the lower-left and upper-right corners of the rectangle using the operator and option. Consider the following prototype query:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
3

The following query returns all documents that have coordinates that exist within the rectangle where the lower-left corner is at

db.collection.find( { <location field> : { $near : [ x , y ] , $maxDistance : <distance> } } )
4 and the upper-right corner is at
db.collection.find( { <location field> : { $near : [ x , y ] , $maxDistance : <distance> } } )
5, using a geospatial index on the
{
   "ns" : "test.places",
   "results" : [
      {
         "dis" : 3,
         "obj" : {
            "_id" : ObjectId(" ... "),
            "loc" : [
               -73,
               39
            ]
         }
      }
   ],
   "stats" : {
      "time" : 2,
      "btreelocs" : 0,
      "nscanned" : 1,
      "objectsLoaded" : 1,
      "avgDistance" : 3,
      "maxDistance" : 3.0000188685220253
   },
   "near" : "0110000111111000000111111000000111111000000111111000",
   "ok" : 1
}
5 field:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
4

Polygons

New in version 1.9: Support for polygon queries.

To query for documents with coordinates inside of a polygon, specify the points of the polygon in an array, using the operator with the option. MongoDB automatically connects the last point in the array to the first point. Consider the following prototype query:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
5

The following query returns all documents that have coordinates that exist within the polygon defined by

db.collection.find( { <location field> : { $near : [ x , y ] , $maxDistance : <distance> } } )
9:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
6

Query for Exact Matches

You can use the method to query for an exact match on a location. These queries have the following form:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
7

This query will return any documents with the value of

db.runCommand( { geoNear: <collection>, near: [ x, y ], maxDistance: <distance> } )
1.

Exact geospatial queries only applicability for a limited selection of cases, the and queries provide more useful results for more applications.

Calculate Distances Using Spherical Geometry

When you query using the

{ "_id" : ObjectId(" ... "), "loc" : [ -73, 39 ] }
2 index, MongoDB calculates distances using flat geometry by default, which models points on a flat surface.

Optionally, you may instruct MongoDB to calculate distances using spherical geometry, which models points on a spherical surface. Spherical geometry is useful for modeling coordinates on the surface of Earth.

To calculate distances using spherical geometry, use MongoDB’s spherical query operators and options:

  • method with the operator.
  • method with the .
  • command with the
    db.runCommand( { geoNear: <collection>, near: [ x, y ], maxDistance: <distance> } )
    
    8 option.

See also

.

For more information on differences between flat and spherical distance calculation, see .

Distance Multiplier

The

db.runCommand( { geoNear: <collection>, near: [ x, y ], maxDistance: <distance> } )
9 option returns distances only after multiplying the results by command by an assigned value. This allows MongoDB to return converted values, and removes the requirement to convert units in application logic.

Note

Because

db.runCommand( { geoNear: <collection>, near: [ x, y ], maxDistance: <distance> } )
9 is an option to , the multiplication operation occurs on the process. The operation adds a slight overhead to the operation of .

Using

db.runCommand( { geoNear: <collection>, near: [ x, y ], maxDistance: <distance> } )
9 in spherical queries allows one to use results from the command without radian to distance conversion. The following example uses
db.runCommand( { geoNear: <collection>, near: [ x, y ], maxDistance: <distance> } )
9 in the command with a example:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
8

The output of the above operation would resemble the following:

copy

db.places.find( { loc: { $near: [ -70, 40 ] } } )
9

See also

The .

Querying Haystack Indexes

Haystack indexes are a special

{ "_id" : ObjectId(" ... "), "loc" : [ -73, 39 ] }
2 geospatial index that optimized to return results over small areas. To create geospatial indexes see .

To query the haystack index, use the command. You must specify both the coordinate and other field to , which take the following form:

copy

{ "_id" : ObjectId(" ... "), "loc" : [ -73, 39 ] }
0

For example, to return all documents with the value

db.runCommand( { geoNear: <collection>, near: [ x, y ], num: z } )
2 in the
db.runCommand( { geoNear: <collection>, near: [ x, y ], num: z } )
3 field near the example point, the command would resemble:

copy

{ "_id" : ObjectId(" ... "), "loc" : [ -73, 39 ] }
1

Note

Haystack indexes are not suited to returning a full list of the closest documents to a particular location, as the closest documents could be far away compared to the

db.runCommand( { geoNear: <collection>, near: [ x, y ], num: z } )
4.

Note

are not currently supported by haystack indexes.

The method and command cannot access the haystack index.

←   Indexing Strategies 2d Geospatial Indexes  →

© MongoDB, Inc 2008-present. MongoDB, Mongo, and the leaf logo are registered trademarks of MongoDB, Inc.