I have a document that contains a LineString. Is it possible to find and return the closest point within the LineString based on a pair of coordinates?
db.paths.find(
{
loc : {
$near : {
$geometry : {
type : "Point" ,
coordinates : [-73.965355,40.782865]
},
$maxDistance : 20000
}
}
);
// My "path" document
loc:{
"type": "LineString",
"coordinates": [
[-2.551082,48.5955632],
[-2.551229,48.594312],
[-2.551550,48.593312],
[-2.552400,48.592312],
[-2.553677, 48.590898]
]
}
As of MongoDB v2.4 (Currently v3.2), LineString is one of the supported GeoJSON objects. See GeoSpatial: GeoJSON Objects
Once you create 2dsphere index to the loc field, you could query closest points.
Using your example document, a mongo shell query would be :
db.paths.find({
location:{
$nearSphere:{
$geometry:{
type:"Point",
coordinates:[-2.551010, 48.59123]
},
$maxDistance:2000
}
}
});
Note that $maxDistance is in meters. Your example find() coordinates is far beyond the maximum distance you specified.
For v3.2 information please see $nearSphere or $near operators.
Related
I have field location array for coordinates
{
location: [13.3339, 80.1943],
...someOtherfield
}
can I use $near in mongoose with that data? specifically in mongoose aggregate?
or I must change data field like this
{
location: {
type: { type: 'Point' },
coordinates: [13.3339, 80.1943],
},
}
Your document implies that you are storing location using Legacy Coordinate Pairs
location: [<longitude>, <latitude> ]
Yes, you can use $near with your data, if you have 2d index, on your location field. 2d index
After that, You can query like this
db.collection.find(
{ location : { $near : [ -73.9667, 40.78 ], $maxDistance: 0.10 } }
)
You can refer it from here
i noticed that mongoDB $near and $geoNear returns around 1km bigger distance than should be.
Point1 (current location):
lat: 54.8985,
long: 23.9036,
Point2 (location in DB):
"location" : {
"type" : "Point",
"coordinates" : [
54.91689,
23.97423
]
}
based on multiple libraries distance should be around 4.7KM
however mongodb returns: "calcDistance" : 8082 = 8km
DIFFERENCE is 4 KM!
You can check it here:
I have tried both spherical and non-spehrical and tried both $geowNear and $near
my code:
db.getCollection('collection').aggregate([
{
$geoNear: {
near: { type: 'Point', coordinates: [ 54.8985, 23.9036 ] },
distanceField: 'calcDistance',
maxDistance: 5 * 1000,
}
}
])
Any ideas why?
Look slike $near and $geoNear need lat and long swapped. That was a problem.
Refer to this: geoNear returns incorrect distance
I have a route that does a $near search on my mongo database. It returns documents that have a geo tag within 100 miles. This request searches each document for "bandLocation". I have a second field, that is indexed, called bandTour - It holds several other geo locations in the same format. I want the request to also include these locations but have been unsuccessful - How do I add the second query?
Here is my route - If "bandLocation" is the only request, it works... How would I add "bandTour"?
router.get('/allbands/:lng/:lat', (req, res) => {
quoteGenerator.find(
{
"bandLocation.geometry":
{ $near :
{
$geometry: {
type: "Point",
coordinates: [parseFloat(req.params.lng), parseFloat(req.params.lat)]
},
$maxDistance: 160934,
}
},
"bandTour.geometry":
{ $near :
{
$geometry: {
type: "Point",
coordinates: [parseFloat(req.params.lng), parseFloat(req.params.lat)]
},
$maxDistance: 160934,
}
}
})
.then(
function(bands){
res.send(bands)
}
)
});
MongoDB only supports a single geo-expressions such as $near in a query. While aggregation does support geo queries, it is only supported as the first stage of the pipeline, so aggregation is not a solution in this case.
You would need to implement this as 2 queries, then combine the results. Since your sample query is requiring both locations to match, you could use a find with $near on bandLocation, projecting just the _id field. Then use the returned _id values to build a second query that tests for _id:{$in:[_array of ids_]} along with the $near on bandTour
In my application I would like to query items that are close by (e.g. within 5km) to a coordinate and I tried to use $near to achieve that. With a quick look I thought it worked but after I tested it further it seems the query is somewhat inaccurate. Here is my setup:
I selected 2 coordinates that are a bit less than 5km apart from each other:
61.4644750214197, 23.8426943813556
61.497133399999996, 23.778528100000003
(At least according to tools like this, this or this the distance between those coordinates should be about ~4,99km)
I added one of the coordinates into empty "items" collection:
db.items.insert({
"geo" : {
"type" : "Point",
"coordinates" : [
61.4644750214197,
23.8426943813556
]
}
});
I added "2dsphere" index to the collection make geospatial queries possible:
db.items.createIndex( { geo : "2dsphere" } )
Finally, I used the other coordinate with $near query:
db.items.find({geo: {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ 61.497133399999996, 23.778528100000003 ]
},
$maxDistance: 5000 // according to docs with '2dsphere' index and GeoJSON this is is meters
}
}}).count()
I expected the result to be 1 but instead it is 0. Even if I set $maxDistance to 7000 the result is still 0, but if I set it to 8000 the result will be 1.
Am I doing something wrong or are MongoDB geospatial queries (or just $near query?) that inaccurate? If so, is there a better way to get accurate results for this kind of query? This is my first time dealing with geospatial queries in MongoDB so there is probably a trivial explanation for my problem.
EDIT:
Basically I was dreaming of a functionality to show all items in map within X kilometres from users current location and X could be determined by user. It would be awkward if an item within 5km would not be visible even when the user wants to filter items within 7km.
I have tried most of the options for doing this query, like $centerSphere, $nearSphere and geoNear with similar results. They all seem to claim that the distance between my earlier mentioned coordinates is somewhere between 7-8km. I'm starting to think either 1. I'm missing some key peace of information about how distances work in general or 2. it simply is not possible to solve my problem with mongodb. Below are my queries for the other options:
$centerSphere (0 results with 5, 6 and 7km but 1 result with 8km):
db.items.find( { geo: {
$geoWithin: { $centerSphere: [ [ 61.497133399999996, 23.778528100000003 ], 5/6378.1 ]
}
}}).count()
geoNear (0 results with maxDistance 5000, 6000 and 7000 but 1 result with 8000):
db.runCommand(
{
geoNear: "items",
near: { type: "Point", coordinates: [ 61.497133399999996, 23.778528100000003 ] },
spherical: true,
maxDistance: 5000
}
)
I understand I am late to the party, but for all those who are facing similar issue
The problem here is that when you store that data into "coordinates", it must be in the [longitude, latitude] order because this is how mongodb works. https://docs.mongodb.com/manual/geospatial-queries/#spherical I just ran your example with reversed order of coordinates and it worked as expected.
db.items.insert({
"geo" : {
"type" : "Point",
"coordinates" : [
23.8426943813556,
61.4644750214197
]
}
});
And then i ran
db.items.find({geo: {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ 23.778528100000003 , 61.497133399999996]
},
$maxDistance: 5000
}
}}).count()
The count here is 1:
Hope it helps
I'm having a series of points which forms a poly-line (path). I need to store it in the mongodb and query it nearby point.
How to store a poly-line in the mongodb?
Can i query it with a $near?
After saving the poly-line to mongodb, i will have a point and distance from the point and need to query the db.
EDIT :
i'm gone track the user's location using the GPS and i need to save the path in mongodb, how to do this?
Then the user can able to search path nearby his place with certain distance so i need to search the mongodb with the $near function.
So what you want is actually a LineString GeoJSON type, which is supported by MongoDB:
{
"loc": {
"type": "LineString",
"coordinates": [ [ 40, 5 ], [ 41, 6 ] ]
}
}
This allows you record a set of "coordinates" along a "path" that you wish to contain as a singular object in your data store. The main beauty of this is that you can do geospatial queries against such an object ( rather than a distinct "Point" and retrieve the whole "set" of connecting "Points" in a single document as "nearest". Better yet "multiple shapes" like this can be matched with ease.
So then you can just query with $near or other operators as appropriate:
db.collection.find({
"loc": {
"$near": {
"$geometry": {
"type": "Point",
"coordinates": [ 41,5 ]
},
"$maxDistance": 10000
}
}
})
A $near operator in a query will return the results ordered by the "nearest" to the queried GeoJSON object or legacy coordinate point provided to the query.
That should basically work for you.