Moe Loepi
unread,Sep 23, 2010, 3:40:54 PM9/23/10Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to mongodb-user
Hello Everyone,
I am currently working on a mongo database which contains a lot of
geodata. I want to query the objects within a certain range given in
kilometres.
As the distance model of the current production release is rathing
confusing, I was happy to see that Mongo 1.7 introduced a new
spherical model which should make it easier to perform this task.
To illustrate the problem, I created a sample dataset of geodata:
db.sights.insert({ name : 'Trafalgar Square' , city : 'London', loc :
[-0.1275,51.507778] });
db.sights.insert({ name : 'Piccadilly Circus' , city : 'London', loc :
[-0.134529,51.509861] });
db.sights.insert({ name : 'London Bridge' , city : 'London', loc :
[-0.087778,51.508056] });
db.sights.insert({ name : 'Hyde Park' , city : 'London', loc :
[-0.169644,51.507327] });
db.sights.insert({ name : 'Eiffel Tower' , city : 'Paris', loc :
[2.2945,48.8583] });
db.sights.insert({ name : 'Van Gogh Museum' , city : 'Amsterdam',
loc : [4.881053,52.358236] });
db.sights.insert({ name : 'Brandenburg Gate' , city : 'Berlin', loc :
[13.377722,52.516272] });
db.sights.insert({ name : 'Stonehenge' , city : 'Amesbury', loc :
[-1.826389,51.178889] });
db.sights.ensureIndex( { loc : "2d" } )
Starting from Trafalgar Square these are the distances according to
Google Maps:
Trafalgar Square: 0 km
Piccadilly Circus: 0.54 km
London Bridge: 2.76 km
Hyde Park: 2.92 km
Eiffel Tower: 341.3 km
Van Gogh Museum: 356.77 km
Brandenburg Gate: 931.52 km
Stonehenge: 123.76 km
First I wanted to see, how accurate MongoDB's spherical distance model
is (second column: distance, third column: distance * 6371 to get km)
db.runCommand( { geoNear : "sights", near: [ -0.1275, 51.507778 ],
spherical : true } )
Piccadilly Circus 0,000084633 0.54
London Bridge 0,000431487 2.75
Hyde Park 0.00457871 2.92
Eiffel Tower 0.053574796 341.33
Van Gogh Museum 0.055892458 356.1
Brandenburg Gate 0.145924356 929.68
Stonehenge 0.019390261 123.54
Wow! That works pretty well.
After that I wanted to write a query which returns all objects within
a certain range. My first approach was:
db.sights.find({"loc" : {"$within" : {"$centerSphere" :
[[-0.1275,51.507778], 1]}}});
This gives me following error: "Spherical distance would require
wrapping, which isn't implemented yet" (Code: 13462)
Ok, well, it's a development release. So I tried using the geoNear
command setting a maxDistance
db.runCommand( { geoNear : "sights", near: [ -0.1275, 51.507778 ],
maxDistance : 0.02, spherical : true } )
For some reason this only returns four objects:
Trafalgar Square, Piccadilly Cirucs, London Bridge, Hyde Park.
According to the geoNear command without maxDistance Stonehenge has a
distance of 0.019, so shouldn't it be included within this query?
Using trial and error I found out, that a maxDistance of
0.000953617217 returns 4 objects within London while 0.000953617216
returns only one. This number doesn't seem to correlate with the
distance number, so I'm not quite sure, what it does.
This leads to following questions:
- Is this a bug of the development release or did I miss something?
- Is there a (simple) approach to solve that task (query objects
within a certain range given in km)? Preferably something that can be
used on a production release of MongoDB and that performs well even
with millions of datasets.
Any hint would be appreciated.
Moe