I have a dataset of ~400k objects in the format:
{
"trip": {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-73.9615,
40.6823
],
[
-73.9704,
40.7849
]
]
},
"properties": {
......
}
}
}
I tried making a 2dsphere index on mLab like so:
{"trip.geometry" : "2dsphere"}
Which I assume just calls:
db.collection.createIndex( {"trip.geometry" : "2dsphere"} )
When I try to do a $geoWithin query like so (about 500 hits):
db.collection.find(
{
"trip.geometry": {
$geoWithin: {
$geometry: {
type : "Polygon" ,
coordinates: [
[
[-74.0345,40.7267],
[-73.9824,40.7174],
[-73.9934,40.7105],
[-74.0345,40.7267]
]
]
}
}
}}
)
I noticed it was very slow, ~2 seconds. I then tried deleting the index entirely, and the time increase was very slight. ~0.5 seconds. Is it possible that this query is not using the index the I had set? I've included the explain() here.
By my interpretation, the winning plan first fetches all the data based on a simple filter, then uses the 2dindex. Shouldn't it start out using the 2dindex, given that the lat and lon data aren't indexed directly?
Related
So I have a query I am running at the moment which allows me to allow a business to show up if a person is within 10km.
However I want to add the ability to also show people if the user is inside a polygon.
I want to be able to do both queries at the same time in one query.
db.geom.insert({
"polygons": {
"type":"Polygon",
"coordinates": [[
[ 17.60083012593064, 78.18557739257812],
[ 17.16834652544664, 78.19381713867188],
[ 17.17490690610013, 78.739013671875],
[ 17.613919673106714, 78.73489379882812],
[ 17.60083012593064, 78.18557739257812]
]]
}
});
To do the polygon query I can do this.
db.geom.find({
polygons: {
$geoIntersects: {
$geometry: {
"type": "Point",
"coordinates": [17.3734, 78.4738]
}
}
}
});
I currently have a query that does this.
advertquery = { location:{ $geoWithin:{ $centerSphere: [ [ parseFloat(docs.location.coordinates[0]), parseFloat(docs.location.coordinates[1])], 10 / 6378.1] } } };
//START COUNT
var adquery = GEMS.countDocuments(advertquery).exec(function(err, count){
adcount = count
});
To get these two queries to work I have had to write this code.
advertquery = {
$or: [
{location:{
$geoIntersects: {
$geometry: {
"type": "Point",
"coordinates": [17.3734, 78.4738]
}
}
}
},
{ location:{
$geoWithin:{
$centerSphere: [ [ 17.3734, 78.4738], 10 / 6378.1] } } }
]
}
//START ADCOUNT
var adquery = GEMS.countDocuments(advertquery).exec(function(err, count){
if(err){console.log(err)}
console.error("TOTAL COUNTED : "+count);
adcount = count
});
However the countDocuments is not returning the count, just 0.
But when I run this is compass I get 1 result.
From the mongodb / mongoose documentation, it states countDocuments() does not support certain operators, that includes $geoWithin that you have used in the above query but can be replaced as mentioned in the docs.
I have a mongo query like this
aggregate([
{
"$geoNear": {
"near": { "type": "Point", "coordinates": [ 35.709770973477255 , 51.404043066431775 ] },
"distanceField": "dist.calculated",
"maxDistance": 5000,
"spherical": True,
"query": { "active_delivery_categories": { "$in" : ["biker"]}, "ban_status": False},
"num": 100
}
}
])
when i add new filed to my query like this:
"query": { "availability_status":"idle","active_delivery_categories": { "$in" : ["biker"]}, "ban_status": False}
response time grow doubles
it happen just on this filed
for example on this query it not happen!
"query": { "city":"London","active_delivery_categories": { "$in" : ["biker"]}, "ban_status": False}
do you have any idea?
One possibility that I can think of is as follows... your original query is able to make use of an appropriate index, and is therefore fast. With the added condition, it is not able to use the index, and is therefore slower.
Look at the .explain() output to see if this is so.
But then, I also notice that you have said it happens only by adding this field. Are you sure of that?
I am experimenting with mongoDB geoNear query. I have a Collection with one document inside:
{
"_id": {
"$oid": "583d169df18ef10012ae8345"
},
"location": {
"loc": [
103.7652117,
1.3150887
],
"name": "",
"_id": {
"$oid": "583d169df18ef10012ae8346"
}
},
}
The location.loc field is 2d indexed. Then I used a geoNear query on mongoDB command
{
"geoNear": "users",
"near": [103.761614, 1.3172431],
"num": 10
}
The result distance returned from mongoDB is 0.004193433515629152 radians which corresponds to more than 20 km. However, these 2 coordinates are just 0.5 km apart. Is there anything I have done wrong? I know it must be some very silly thing, but I just couldn't figure out.
If you want to query related to $geoWithin or $centerSphere or $geoNear location structure like this only:-
"location" : {
"lng" : 77.15319738236303,
"lat" : 28.434568229025803
},
And then run your query. It will give you accurate result.
I'm trying to make use of some geolocation functionality in mongodb. Using a find query with $near doesn't seem to work!
I currently have this object in my database:
{
"Username": "Deano",
"_id": {
"$oid": "533f0b722ad3a8d39b6213c3"
},
"location": {
"type": "Point",
"coordinates": [
51.50998,
-0.1337
]
}
}
I have the following index set up as well:
{
"v": 1,
"key": {
"location": "2dsphere"
},
"ns": "heroku_app23672911.catchmerequests",
"name": "location_2dsphere",
"background": true
}
When I run this query:
db.collectionname.find({ "location" : { $near : [50.0 , -0.1330] , $maxDistance : 10000 }})
I get this error:
error: {
"$err" : "can't parse query (2dsphere): { $near: [ 50.0, -0.133 ], $maxDistance: 10000.0 }",
"code" : 16535
}
Does anyone know where I'm going wrong? Any help would be much appreciated!
It seems you need to use the GeoJSON format if your data is in GeoJSON format too, as yours is. If you use:
db.collectionname.find({
"location": {
$near: {
$geometry:
{ type: "Point", coordinates: [50.0, -0.1330] }, $maxDistance: 500
}
}
})
it should work. I could replicate your error using GeoJSON storage format for the field, but what the docs call legacy points in the query expression. I think the docs are a bit unclear in that they suggest you can use both GeoJSON and legacy coordinates with a 2dsphere index 2dsphere
I am using 2.4.10, for what it is worth, as there were some big changes to spatial in the 2.4 release.
This isn't exactly a solution as I never got the above working, but using geoNear I managed to get what I wanted.
db.runCommand( { geoNear : 'catchmerequests', near:
{ type: 'Point', coordinates : [50, 50] }, spherical : true } );
If anyone can find out why the original $near attempt failed that would still be appreciated, but I'm posting this for anyone else who else who is looking for a working alternative.
I would like to have a MongoDB collection and each document contains a geospatial polygon defined by latitude/longitude points (in GeoJSON). Then, I would like to take any given longitude/latitude point and check if it resides within any of the MongoDB polygons defined in the documents. Hypothetically, this is what the documents would look like.
{
"type" : "congressional",
"points" : [
{ "coords" : [
-141.0205,
70.0187 ]
},
...
{ "coords" : [
-141.0205,
70.0187 ]
}
]
}
Or maybe like so:
{ loc :
{ type : "Polygon" ,
coordinates : [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ] ]
} }
And then I would query it, hypothetically, like so (most likely with Mongo's $geoWithin):
db.places.find( { loc : { $geoWithin : { $geometry : "EACH DOCUMENT IN COLLECTION"} } } )
Is geofencing, or something similar, possible to do with the current MongoDB feature-set? If so, how would it be done?
I believe you would have to first find every document from the collection., and then make a "$geoWithin" query for every document, passing in the Polygon to test against for each case.
Depending on the number of documents in your collection, that may or may not provide sufficient performance.
MongoDB has full support for geofencing or finding documents whose geometry intersects with a given geometry (point, polygon). The query below is an example. geometry of Collection is the field containing the geometry.
Document Example:
{ "geometry": {
"type": "Polygon",
"coordinates": [
[
[
-74.001487,
40.692346
],
[
-74.001755,
40.692057
],
[
-74.000977,
40.691951
],
[
-74.000827,
40.692297
],
[
-74.001487,
40.692346
]
]
]
}
}
JS Query:
//find quests bots that matches the users location
await Collection.find({ geometry:
{ $geoIntersects:
{
{
type: "Point",
coordinates: [
-73.99460599999999,
40.7347229
]
}
}
}
});