1Geospatial Indexing Example 2=========================== 3 4.. testsetup:: 5 6 from pymongo import MongoClient 7 client = MongoClient() 8 client.drop_database('geo_example') 9 10This example shows how to create and use a :data:`~pymongo.GEO2D` 11index in PyMongo. To create a spherical (earth-like) geospatial index use :data:`~pymongo.GEOSPHERE` instead. 12 13.. mongodoc:: geo 14 15Creating a Geospatial Index 16--------------------------- 17 18Creating a geospatial index in pymongo is easy: 19 20.. doctest:: 21 22 >>> from pymongo import MongoClient, GEO2D 23 >>> db = MongoClient().geo_example 24 >>> db.places.create_index([("loc", GEO2D)]) 25 u'loc_2d' 26 27Inserting Places 28---------------- 29 30Locations in MongoDB are represented using either embedded documents 31or lists where the first two elements are coordinates. Here, we'll 32insert a couple of example locations: 33 34.. doctest:: 35 36 >>> result = db.places.insert_many([{"loc": [2, 5]}, 37 ... {"loc": [30, 5]}, 38 ... {"loc": [1, 2]}, 39 ... {"loc": [4, 4]}]) # doctest: +ELLIPSIS 40 >>> result.inserted_ids 41 [ObjectId('...'), ObjectId('...'), ObjectId('...'), ObjectId('...')] 42 43.. note:: If specifying latitude and longitude coordinates in :data:`~pymongo.GEOSPHERE`, list the **longitude** first and then **latitude**. 44 45Querying 46-------- 47 48Using the geospatial index we can find documents near another point: 49 50.. doctest:: 51 52 >>> import pprint 53 >>> for doc in db.places.find({"loc": {"$near": [3, 6]}}).limit(3): 54 ... pprint.pprint(doc) 55 ... 56 {u'_id': ObjectId('...'), u'loc': [2, 5]} 57 {u'_id': ObjectId('...'), u'loc': [4, 4]} 58 {u'_id': ObjectId('...'), u'loc': [1, 2]} 59 60.. note:: If using :data:`pymongo.GEOSPHERE`, using $nearSphere is recommended. 61 62The $maxDistance operator requires the use of :class:`~bson.son.SON`: 63 64.. doctest:: 65 66 >>> from bson.son import SON 67 >>> query = {"loc": SON([("$near", [3, 6]), ("$maxDistance", 100)])} 68 >>> for doc in db.places.find(query).limit(3): 69 ... pprint.pprint(doc) 70 ... 71 {u'_id': ObjectId('...'), u'loc': [2, 5]} 72 {u'_id': ObjectId('...'), u'loc': [4, 4]} 73 {u'_id': ObjectId('...'), u'loc': [1, 2]} 74 75It's also possible to query for all items within a given rectangle 76(specified by lower-left and upper-right coordinates): 77 78.. doctest:: 79 80 >>> query = {"loc": {"$within": {"$box": [[2, 2], [5, 6]]}}} 81 >>> for doc in db.places.find(query).sort('_id'): 82 ... pprint.pprint(doc) 83 {u'_id': ObjectId('...'), u'loc': [2, 5]} 84 {u'_id': ObjectId('...'), u'loc': [4, 4]} 85 86Or circle (specified by center point and radius): 87 88.. doctest:: 89 90 >>> query = {"loc": {"$within": {"$center": [[0, 0], 6]}}} 91 >>> for doc in db.places.find(query).sort('_id'): 92 ... pprint.pprint(doc) 93 ... 94 {u'_id': ObjectId('...'), u'loc': [2, 5]} 95 {u'_id': ObjectId('...'), u'loc': [1, 2]} 96 {u'_id': ObjectId('...'), u'loc': [4, 4]} 97 98geoNear queries are also supported using :class:`~bson.son.SON`:: 99 100 >>> from bson.son import SON 101 >>> db.command(SON([('geoNear', 'places'), ('near', [1, 2])])) 102 {u'ok': 1.0, u'stats': ...} 103 104.. warning:: Starting in MongoDB version 4.0, MongoDB deprecates the **geoNear** command. Use one of the following operations instead. 105 106 * $geoNear - aggregation stage. 107 * $near - query operator. 108 * $nearSphere - query operator. 109