GeoLocation query in mongo db - mongodb

How Could i get longitude and lattitude using mongodb query from mongo collection
based on disatnce and certain coordinates.
{
"_id" : ObjectId("5a559b13ae201d0c05cb6f6a"),
"id" : "99623",
"city" : "Wasilla",
"cnty" : "Matanuska Susitna",
"cntyFips" : null,
"st" : "AK",
"stName" : "Alaska",
"areaCode" : "907",
"lat" : 61.5816,
"long" : -149.4393,
"rgn" : "West",
"__v" : 0
}
in this document "lat" is for latitude and "long" is for longitude.
so basically i have to get all ids based on present id lat and long which comes in a particular miles distance range.

Mongo supports GeoJSON which should allow you to perform basic queries easily on these kind of data. Examples include $geoWithin for your particular use-case.

We need a little more information on the structure of the documents that you are querying, but here is a simple example of the query available in the Mongo documentation here.
It's worth noting that you require a 2dsphere index for location data defined as GeoJSON points in order for this to be effective.
{
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ <longitude>, <latitude> ]
},
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}

Related

What is the correct way to query this document? (If the index is correct)

I've a BigChainDB docker container running in my machine and I'm trying to store and retrieve geospatial data.
I've created through the MongoDB interface a 2dsphere index "location" in the "metadata" collection.
I've checked with the command:
db.people.getIndexes()
And I think that everything it's ok, in fact the result is this:
{
"v" : 2,
"key" : {
"loc" : "2dsphere"
},
"name" : "loc_2dsphere",
"ns" : "bigchain.metadata",
"2dsphereIndexVersion" : 3
}
The document that I've inserted to try some spatial queries is (this is the result of a db.metadata.findOne() query):
{
"_id" : ObjectId("5ccab10a2ce1b70022823a0f"),
"id" : "752ee9abccf83c7fd25d86c9a7d12229ae292fa27544f6881f1dbf97ccd8b413",
"metadata" : {
"location" : {
"type" : "Point",
"coordinates" : [
22.170872,
113.578749
]
}
}
}
But when I use this spatial query nothing is retrieved:
db.metadata.find(
{
"metadata": {
"location": {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ 22 , 113 ]
},
}
}
}
})
I'm doing anything wrong, or is there the possibility that the index doesn't work?
There are a couple of issues here.
The first is that the index is on the field loc whereas your query is querying metadata.location.
If you try creating a 2dsphere index on metadata.location you will see the 2nd error:
"errmsg" : "invalid point in geo near query $geometry argument: { type: \"Point\", coordinates: [ 22.0, 113.0 ] } longitude/latitude is out of bounds, lng: 22 lat: 113",
This error shows that the GEOJSON point defined in your document is invalid, as the latitude value of 113 is outside the acceptable range of [-90, 90].
You would need to correct the data to be valid GEOJSON before indexing.

Return distance for each coordinates in mongodb [duplicate]

When I am firing this query on MongoDB, I am getting all the places in the proximity of 500 miles to the specified co-ordinates. But I want to know the exact distance between the specified co-ordinates and the result location.
db.new_stores.find({ "geometry": { $nearSphere: { $geometry: { type: "Point", coordinates: [ -81.093699, 32.074673 ] }, $maxDistance: 500 * 3963 } } } ).pretty()
My Output looks like:
{
"_id" : ObjectId("565172058bc200b0db0f75b1"),
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [
-80.148826,
25.941116
]
},
"properties" : {
"Name" : "Anthony's Coal Fired Pizza",
"Address" : "17901 Biscayne Blvd, Aventura, FL"
}
}
I also want to know the distance of this place from the specified co-ordinate. I created 2dsphere index on geometry.
You can use the $geoNear aggregate pipeline stage to produce a distance from the queried point:
db.new_stores.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -81.093699, 32.074673 ]
},
"maxDistance": 500 * 1609,
"key" : "myLocation",
"spherical": true,
"distanceField": "distance",
"distanceMultiplier": 0.000621371
}}
]).pretty()
This allows you to specify "distanceField" which will produce another field in the output documents containing the distance from the queried point. You can also use "distanceMultiplier" to apply any conversion to the output distance as required ( i.e meters to miles, and noting that all GeoJSON distances are returned in meters )
There is also the geoNear command with similar options, but it of course does not return a cursor as output.
if you have more than one 2dsphere, you should specify a "key".
MongoDB provides a $geoNear aggregator for calculating the distance of documents in a collection with GeoJson coordinates.
Let us understand it with a simple example.
Consider a simple collection shops
1. Create Collection
db.createCollection('shops')
2. Insert documents in shops collections
db.shops.insert({name:"Galaxy store",address:{type:"Point",coordinates:[28.442894,77.341299]}})
db.shops.insert({name:"A2Z store",address:{type:"Point",coordinates:[28.412894,77.311299]}})
db.shops.insert({name:"Mica store",address:{type:"Point",coordinates:[28.422894,77.342299]}})
db.shops.insert({name:"Full Stack developer",address:{type:"Point",coordinates:[28.433894,77.334299]}})
3. create GeoIndex on "address" fields
db.shops.createIndex({address: "2dsphere" } )
4. Now use a $geoNear aggregator
to find out the documents with distance.
db.shops.aggregate([{$geoNear:{near:{type:"Point",coordinates:[28.411134,77.331801]},distanceField: "shopDistance",$maxDistance:150000,spherical: true}}]).pretty()
Here coordinates:[28.411134,77.331801] is the center position or quired position from where documents will be fetched.
distanceField:"shopDistance" , $geoNear Aggregator return shopDistance as fields in result.
Result:
{ "_id" : ObjectId("5ef047a4715e6ae00d0893ca"), "name" : "Full Stack developer", "address" : { "type" : "Point", "coordinates" : [ 28.433894, 77.334299 ] }, "shopDistance" : 621.2848190449148 }
{ "_id" : ObjectId("5ef0479e715e6ae00d0893c9"), "name" : "Mica store", "address" : { "type" : "Point", "coordinates" : [ 28.422894, 77.342299 ] }, "shopDistance" : 1203.3456146763526 }
{ "_id" : ObjectId("5ef0478a715e6ae00d0893c7"), "name" : "Galaxy store", "address" : { "type" : "Point", "coordinates" : [ 28.442894, 77.341299 ] }, "shopDistance" : 1310.9612119555288 }
{ "_id" : ObjectId("5ef04792715e6ae00d0893c8"), "name" : "A2Z store", "address" : { "type" : "Point", "coordinates" : [ 28.412894, 77.311299 ] }, "shopDistance" : 2282.6640175038788 }
Here shopDistance will be in meter.
maxDistance -> Optional. The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point.
Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs.
In the docs it says if you use legacy pairs , eg : near : [long , lat] , then specify the maxDistance in radians.
If you user GeoJSON , eg : near : { type : "Point" , coordinates : [long ,lat] },
then specify the maxDistance in meters.
Use $geoNear to get the distance between a given location and users.
db.users.aggregate([
{"$geoNear": {
"near": {
"type": "Point",
"coordinates": [ longitude, latitude]
},
"distanceField": "distance",
"distanceMultiplier": 1/1000,
"query": {/* userConditions */},
}}
]).pretty()

How do I calculate the total distance traveled with MongoDB

I need to calculate the total distance traveled between a collection of points. They all have a timestamp to get them in the right order. I'm only allowed to use MongoDB.
Sample collection:
{
"_id" : ObjectId("596cd354241aa3174056fb98"),
"spelerID" : 1,
"timestamp" : ISODate("2017-02-01T19:00:00.000Z"),
"coordinates" : {
"type" : "Point",
"coordinates" : [
4.29870386367084,
50.8357637566422
]
}
}
/* 2 */
{
"_id" : ObjectId("596cd354241aa3174056fbb4"),
"spelerID" : 1,
"timestamp" : ISODate("2017-02-01T19:00:01.000Z"),
"coordinates" : {
"type" : "Point",
"coordinates" : [
4.29868458167181,
50.8357575419868
]
}
}
/* 3 */
{
"_id" : ObjectId("596cd354241aa3174056fbce"),
"spelerID" : 1,
"timestamp" : ISODate("2017-02-01T19:00:02.000Z"),
"coordinates" : {
"type" : "Point",
"coordinates" : [
4.29867536067721,
50.8357376028214
]
}
}
I have no idea how to calculate the distance between those points in the right order.
MongoDB can performance the distance between two points by using $near or $geoNear.
Returns documents in order of proximity to a specified point, from the nearest to farthest. geoNear requires a geospatial index.
https://docs.mongodb.com/manual/reference/command/geoNear/
In your case I don't think this will resolve the issue since you want to perform multiple distance calculation between multiple points.
MongoDB can be instruct to create very complex algorithm by using MapReduce. Even if I'm not expert in GIS application you could try to create a MapReduce routine with a Function that compute the distance between multiple points ordered as you like.
MongoDB - MapReduce
This link can help you to write a JS function to be used in Map Reduce:
Calculate distance between two latitude-longitude points? (Haversine formula)
Good Luck!

mongodb geospacial query : $centerSphere not giving good result

I have a db with geodata (lng,lat) from Europe.
I'm trying to do a geospatial query to get all element within a circle.
So, i create a GeoJSON field, and a 2dsphere index on it.
This look like that :
{
"_id" : ObjectId("56c3484612aeb853a83ec336"),
"defaultLabel" : "Zoo de Mulhouse",
"weight" : NumberInt(1),
"country" : "FR",
"loc" : {
"type" : "Point",
"coordinates" : [
47.731673,
7.347819
]
}
}
and db.myCollection.createIndex({"loc":"2dsphere"});
So far, so good.
But then i tried some queries to check.
I took a point at ~1,12 km (1120m) from the data, and did a request with a radius of 1200m.
db.poi.find({loc:
{$geoWithin:
{$centerSphere:[
[47.728593,7.333486],
1200 / 6378100] // radius of earth ~6378.1Km
}
}
})
I got no result.
With the same request, i have to put about 1650m to get the result.
Obviously, this is not acceptable.
So, what did I do wrong?
Found the problem : coordinates were stored as [lat,lgn] in my legacy, and i didn't check before create my GeoJSON, so it was in the wrong order.

MongoDB print distance between two points

When I am firing this query on MongoDB, I am getting all the places in the proximity of 500 miles to the specified co-ordinates. But I want to know the exact distance between the specified co-ordinates and the result location.
db.new_stores.find({ "geometry": { $nearSphere: { $geometry: { type: "Point", coordinates: [ -81.093699, 32.074673 ] }, $maxDistance: 500 * 3963 } } } ).pretty()
My Output looks like:
{
"_id" : ObjectId("565172058bc200b0db0f75b1"),
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [
-80.148826,
25.941116
]
},
"properties" : {
"Name" : "Anthony's Coal Fired Pizza",
"Address" : "17901 Biscayne Blvd, Aventura, FL"
}
}
I also want to know the distance of this place from the specified co-ordinate. I created 2dsphere index on geometry.
You can use the $geoNear aggregate pipeline stage to produce a distance from the queried point:
db.new_stores.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -81.093699, 32.074673 ]
},
"maxDistance": 500 * 1609,
"key" : "myLocation",
"spherical": true,
"distanceField": "distance",
"distanceMultiplier": 0.000621371
}}
]).pretty()
This allows you to specify "distanceField" which will produce another field in the output documents containing the distance from the queried point. You can also use "distanceMultiplier" to apply any conversion to the output distance as required ( i.e meters to miles, and noting that all GeoJSON distances are returned in meters )
There is also the geoNear command with similar options, but it of course does not return a cursor as output.
if you have more than one 2dsphere, you should specify a "key".
MongoDB provides a $geoNear aggregator for calculating the distance of documents in a collection with GeoJson coordinates.
Let us understand it with a simple example.
Consider a simple collection shops
1. Create Collection
db.createCollection('shops')
2. Insert documents in shops collections
db.shops.insert({name:"Galaxy store",address:{type:"Point",coordinates:[28.442894,77.341299]}})
db.shops.insert({name:"A2Z store",address:{type:"Point",coordinates:[28.412894,77.311299]}})
db.shops.insert({name:"Mica store",address:{type:"Point",coordinates:[28.422894,77.342299]}})
db.shops.insert({name:"Full Stack developer",address:{type:"Point",coordinates:[28.433894,77.334299]}})
3. create GeoIndex on "address" fields
db.shops.createIndex({address: "2dsphere" } )
4. Now use a $geoNear aggregator
to find out the documents with distance.
db.shops.aggregate([{$geoNear:{near:{type:"Point",coordinates:[28.411134,77.331801]},distanceField: "shopDistance",$maxDistance:150000,spherical: true}}]).pretty()
Here coordinates:[28.411134,77.331801] is the center position or quired position from where documents will be fetched.
distanceField:"shopDistance" , $geoNear Aggregator return shopDistance as fields in result.
Result:
{ "_id" : ObjectId("5ef047a4715e6ae00d0893ca"), "name" : "Full Stack developer", "address" : { "type" : "Point", "coordinates" : [ 28.433894, 77.334299 ] }, "shopDistance" : 621.2848190449148 }
{ "_id" : ObjectId("5ef0479e715e6ae00d0893c9"), "name" : "Mica store", "address" : { "type" : "Point", "coordinates" : [ 28.422894, 77.342299 ] }, "shopDistance" : 1203.3456146763526 }
{ "_id" : ObjectId("5ef0478a715e6ae00d0893c7"), "name" : "Galaxy store", "address" : { "type" : "Point", "coordinates" : [ 28.442894, 77.341299 ] }, "shopDistance" : 1310.9612119555288 }
{ "_id" : ObjectId("5ef04792715e6ae00d0893c8"), "name" : "A2Z store", "address" : { "type" : "Point", "coordinates" : [ 28.412894, 77.311299 ] }, "shopDistance" : 2282.6640175038788 }
Here shopDistance will be in meter.
maxDistance -> Optional. The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point.
Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs.
In the docs it says if you use legacy pairs , eg : near : [long , lat] , then specify the maxDistance in radians.
If you user GeoJSON , eg : near : { type : "Point" , coordinates : [long ,lat] },
then specify the maxDistance in meters.
Use $geoNear to get the distance between a given location and users.
db.users.aggregate([
{"$geoNear": {
"near": {
"type": "Point",
"coordinates": [ longitude, latitude]
},
"distanceField": "distance",
"distanceMultiplier": 1/1000,
"query": {/* userConditions */},
}}
]).pretty()