Reputation: 15154
I have a MongoDB collection with a geo index:
> db.coll.getIndexes()
[
// ...
{
"v" : 1,
"key" : {
"location" : "2dsphere"
},
"ns" : "test.coll",
"dropDups" : false,
"name" : "location_2dsphere",
"background" : false
}
]
db.coll.findOne({location: {'$exists': true}}, {'location': 1})
{
"_id" : ObjectId("52cd72ae2ac170aa3eaace6e"),
"location" : [
55.4545177559,
11.5767419669
]
}
On which I'm running map reduce, which looks something like this:
var map = function() {
var value = 0;
// ... various calculations on the value here
var distance = 0; // < This is the problematic part
if (distance < 1000) {
val += distance; // for example
}
emit(this._id, value)
}
var reduce = function(id, val) {
return {id: val}
}
db.coll.mapReduce(map, reduce, {out: {inline: 1}})
Is there a way to calculate the distance between location
and point X, in the map function?
I'm looking for something like $geoNear, but somehow combined with the map-reduce.
For example:
db.runCommand({geoNear: "coll", near: [-74, 40.74], spherical: true})
Returns the distance for each document. But I can't find a way to combine it with the map-reduce command.
Upvotes: 3
Views: 654
Reputation: 2262
I know this is a late addition but for other folks coming here it might be good to know about a suite of Javascript libraries that are available to do geo related functions.
https://github.com/manuelbieh/Geolib
Upvotes: 1
Reputation: 4001
The Great Circle Formula is the way to go http://en.wikipedia.org/wiki/Great-circle_distance
I ran in to a similar problem with mongo and js. And came up with this function. Hope it helps.
function find(point, latlng, radius){
var dist = parseInt(radius) * 0.868976 / 60; // convert miles to rad
if((point[0] <= latlng[0] + dist && point[1] >= latlng[1]- dist)
&& (point[0] <= latlng[0]+ dist && point[1] >= latlng[1]- dist)){
dx = latlng[0] - point[0];
dy = latlng[1] - point[1];
dx *= dx;
dy *= dy;
ds = dx + dy;
rs = dist * dist;
is = ds <= rs;
return is;
}
}
Im calling this like this:
find([-79,5], [40,20], 5);
Upvotes: 5