Mongodb geospatial query for searching lat, long within a radius - node.js

I am trying to get the results based on geospatial query of mongodb within a circle of 5 km radius of a given lat,long.
For that i am using this query
{coords :
{ $nearSphere :{
$geometry: {
type : "Point",
coordinates : [ data.longitude, data.latitude]
},
$maxDistance: 5000
}
}
}
But it is giving me undefined output. But when i remove the $maxDistance it is giving me all the results. I want to get the results only under the specified maxDistance.

Related

Getting coordinates to near me using node js and mongodb

I am using Node.JS, MongoDB and express.js. I keep coordinates in my database. And I want to get the coordinates to near me. How can I do it?
I thought about converting the meridians to km. I was able to calculate at the equator, but due to the shape of the earth, the distance between the meridian was not equal everywhere. I couldn't find any other solution.
My coordinate parameter in Mongo Model:
coordinate: {
type: String,
},
Example value:
coordinate: "41.08112226606513,29.066728949546814"
{
<location field>: {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ <longitude> , <latitude> ]
},
$maxDistance: <distance in meters>,
$minDistance: <distance in meters>
}
}
}
use this above query in your query
please read this above official document

List locations near by to a lat, lon point from stored lat, lon in database

I have [lat, lon] pairs of different locations stored in MongoDb. Now I want to compare a certain coordinates pair by distance like in circle of 2 km from that point and want to take results of all from database.
You should have a look at geoNear command.
Generic example is the following:
db.runCommand(
{
geoNear: "places", // Your target collection
near: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, // Point coordinates
spherical: true, // 2dsphere index required for using this option
query: { yourField: "someFilterVale" }, // Additional regular filtering
maxDistance: 2000 // Maximum distance in meters/radians
}
)
minDistance is also available for querying
For this purpose you should have 2d or 2dsphere index in your collection.
Also there is a $geoNear aggregation.

How to use $geoNear on array of embedded documents?

My document structure is like the following:
{ agency_key : '',
route_id: '',
direction_id: '',
stops: [
{stop_id:15,
stop_lat: '',
stop_lon: '',
loc: [-83.118972, 42, 121567]
},
{...
}
]
}
I want to find the stops which are close to a given (lat,lon) pair within a given distance from every document in the collection. I created 2d indexes. I tried $unwind, then $geoNear but it says $geoNear can only be at the first stage of the pipeline.
I tried this:
db.tm_stops.aggregate([
... {
... $geoNear: { near: {coordinates: [-82.958841, 42.370114] }, distanceField: "stops.calculated", query: { agency_key: "DDOT"},
... includeLocs: "stops.loc" }
... }
... ])
I tried the following:
db.tm_stops.find({stops:{$near:[-82.958841, 42.370114], $maxDistance: 1 } } )
It throws this error:
error: {
"$err" : "Unable to execute query: error processing query: ns=gtfs.tm_stops limit=0 skip=0\nTree: GEONEAR field=stops maxdist=1 isNearSphere=0\nSort: {}\nProj: {}\n planner returned error: unable to find index for $geoNear query",
"code" : 17007
What should be my mongo query? I will need to execute this from a Node.js application but I want to see some result in Mongo shell first. Thanks in advance.
I finally made the query work. I am answering my own question for future reference.
Since I am using 2d index and not 2dsphere, I didn't have to use coordinates in near operator. This query works:
db.tm_stops.aggregate([
{
$geoNear:
{ near: [-82.958841, 42.370114] ,
distanceField: "stops.calculated",
query: { agency_key: "DDOT"},
includeLocs: "stops.loc" }
}
])
But I discovered, in the returned document, i can only see the calculated distance and the (lon, lat) pair used to calculate the distance. I can't really returned the whole embedded document which is used for the calculation.
If I find a way to return the whole embedded document, I'll update my answer.

Using geoJSON in mongoose schema and use it in a query

I'm new to mongoDB and the usage of geoJSON within it.
I have the following schema I created using the mongoose module:
var mongoose = require('mongoose');
var hikeSchema = mongoose.Schema({
name: String,
area: String,
length: Number,
time: String,
Difficulty: { type : Number, min : 0 , max :5 },
start_coord: {
lon: Number,
lat: Number
},
rank_count: Number,
avg_overall_rating: { type : Number, min : 0 , max :5 },
completed_count: Number,
description: String,
ranking_pages: [
mongoose.Schema.Types.ObjectId
]
});
module.exports = mongoose.model('Hike', hikeSchema);
I used a simple Number type to represent to longitude and latitude inside a sub object within the schema.
I don't know if this is the way to go about it. I want it to be saved as a geoJSON object and then run queries on this object.
I recommand you to see the mongoDB part for geolocation datas : http://docs.mongodb.org/manual/core/2d/
To store longitude, latitude, MongoDB take you the correct data structure to save items :
To store location data as legacy coordinate pairs, use an array or an embedded document.
When possible, use the array format:
loc : [ < longitude > , < latitude > ]
Consider the embedded document form:
loc : { lng : , lat : }
Arrays are preferred as certain languages do not guarantee associative map ordering.
For all points, if you use longitude and latitude, store coordinates in longitude, latitude order.
On your shema, change
start_coord: {
lon: Number,
lat: Number
},
By :
start_coord: {
lng: Number,
lat: Number
},
Then you should add a 2dindex for your field start_coords to use all mongoDB geospatial queries :
db.collection.ensureIndex( { start_coord : "2d" } , { min : <l ower bound > , max : < upper bound > } )
EDIT It's important to set min and max if your longitude and latitude is not a real lng/lat (for example if you could use 2dindexes in a orthonormal map)
Now you can use all geospatial query operators : http://docs.mongodb.org/manual/reference/operator/query-geospatial/
You can also do it this way:
start_coord: {
type: [Number], // [<longitude>, <latitude>]
index: '2d' // create the geospatial index
}
Check this tutorial: How to use geospatial indexing in mongoDb

mongodb's find over nodejs 2d index with $near returns as an empty find

I'm trying to get some results from my places collection which are close to a coordinate. For this purpose, I'm using a 2d index over a location.position attribute which has a lng and lat attribute.
The problem is that every coordinate I put, it returns the same 60 results (the whole collection).
The docs in my collection are all from near to my GPS coordinate and, however, if I put a 0.0, 0.0 coordinate or any other pair, it returns always the same.
In fact, the query returns exactly the same if I use an empty find().
The index seems to be created correctly as it is not returning any error.
An object in my collection is like this:
{ "_id" : "80293840923...",
"name": "myname",
"location" : {
"position" : { "lng": -196988, "lat": 43.30594 }
"address": "example",
"city": "example" }
}
The index is created like this:
places_collection.ensureIndex({"location.position": "2d"}, {name: "index2dLocation"}, function(error, indexName){
callback("", "Indice creado: " + indexName)
});
The search would be like this:
places_collection.find(
{ "location.position" : { $near : [ parseFloat(-123.98) , parseFloat(162.342) ] } }
).toArray(function(error, results) {
if( error ){ callback(error, "")
}else{ console.log(results.length); callback(null, results); }
});
And finally, as said before, my search returns always the same result. It doesn't care if I put one coordinate or another. Even it doesn't care if I make a empty find().
Any help here please? I don't know how to make it work.
Thank you very much.
Finally, the solution was to add the $maxDistance property to avoid all the docs which are more far than the radius in the $maxDistance.
If you don't put that property and you only have 10 docs located near to one coordinate, if you make a find in a very far coordinate, it will still return the same 10 docs because you don't have more docs near to the new coordinate.
In addition, it's important to say that $maxDistance's unit is in degrees, so here was my solution: https://stackoverflow.com/a/7841830/974828
To convert degrees to kilometers, you have to divide by 111.12.
So here is the result:
db.places.find( { loc : { $near : [50,50] , $maxDistance : 1/111.12 } } )

Resources