mongodb and geospatial schema - mongodb

im breaking my head with mongo and geospatial,
so maybe someone has some idea or solution how to solve this:
my object schema is like this sample for geoJSON taken from http://geojson.org/geojson-spec.html.
{
"name":"name",
"geoJSON":{
"type":"FeatureCollection",
"features":[
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[100,0],[101,0],[101,1],[100,1],[100,0]]]},"properties":{}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[100,0],[101,0],[101,1],[100,1],[100,0]]]},"properties":{}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[100,0],[101,0],[101,1],[100,1],[100,0]]]},"properties":{}}
]}}
additional info: I'm using spring data but that shouldn't influence the answer.
main problem is how/where to put indexes in this schema. I need to make a query to find all documents for given Point if some polygon intersects.
thanks in advance.

By creating a 2d or 2dsphere index on geoJSON.features.geometry you should be able to create an index covering all of the geoJSON-objects.
To get all documents where at least one of the sub-object in the features array covers a certain point, you can use the $geoIntersects operator with a geoJSON Point:
db.yourcollection.find(
{ `geoJSON.features.geometry` :
{ $geoIntersects :
{ $geometry :
{ type : "Point" ,
coordinates: [ 100.5 , 0.5 ]
}
}
}
}
)

Related

Mongodb Point inside a Polygon not getting results - Mongoid + Rails

I'm trying to check if a point is inside a polygon with mongodb (mongodb 2.6).
I'm inserting the data in de collection like this:
db.areas.insert({"polygons":
{"type":"Polygon",
coordinates:
[[[-23.0651232, -45.6374645],
[-23.0557255, -45.6435585],
[-23.0370072, -45.6383228],
[-23.0299772, -45.6351471],
[-23.0025649, -45.6480217],
[-22.9723022, -45.6554031],
[-22.9340493, -45.6032181],
[-22.9353140, -45.5925751],
[-22.9383177, -45.5855370],
[-22.9601320, -45.5560112],
[-22.9645577, -45.5597878],
[-22.9938740, -45.5675125],
[-22.9939530, -45.5690575],
[-23.0217620, -45.5712891],
[-23.0241319, -45.5719757],
[-23.0258697, -45.5711174],
[-23.0268966, -45.5721474],
[-23.0656365, -45.6372499],
[-23.0651232, -45.6374645]
]]
}
});
And querying like this:
db.areas.find({polygons:
{$geoIntersects:
{$geometry:{ "type" : "Point",
"coordinates" : [ -22.112, -45.56 ] }
}
}
});
But I'm getting no result. Any ideas?
I've looked this links:
mongodb check if point is in polygon
Search all polygons that contains a series of points in mongodb
Any help will be appreciated
I found the answer.
The problemas was that when I tried to save, the coordinates of the Polygon from a Rails form it was saved as String and not as Double.
I chaged that before save an the problem was solved.

How to find nearby events or tweets

I'm new to NoSQL databases and I'm stuck with a fairly basic query.
I have a collection of tweets in a MongoDB database, which I'm querying through both the Mongo shell and pyMongo. The documents are similar to:
{ loc : { lng : 40, lat : 3 },
timestamp : 124125512,
userid = 55 }
I need to find all pairs of users with events close to each other with less than 4 hours of difference. The most naive way would be:
db.tweets.find().forEach(function(tweet)
{
found = db.tweets.find({ "timestamp": { "$gt" : tweet['timestamp'] - 60*60*4,
"$lt" : tweet['timestamp'] + 60*60*4},
"loc" : {"$near" : [ tweet['loc']['lng'],
tweet['loc']['lat'] ],
"$maxDistance" : 500 }
});
//... extract the users from those tweets...
}
Which of course is extremely slow (it can contain as many as a few million tweets).
I haven't been able to express this query using neither aggregation nor MapReduce. How would you do it? What is the most NoSQL-y, efficient and clear way of making this kind of query?
EDIT: I've kind of given up. I've been convinced by a friend that it is not going to worth it using Mongo for this. I can leverage that time restriction to avoid iterating over the whole collection and do it in a simple, more traditional iterative script. Since it is not such a huge dataset as to not fit in RAM, it's going to be faster.
Use $near in conjuction with $maxDistance is the most recommended way
db.collectionName.find({loc: {$near: [50, 50], $maxDistance: 5}});
For performance issues you can try creating index as mentioned below:
To create a geospatial index for GeoJSON-formatted data, use the ensureIndex() method and set the value of the location field for your collection to 2dsphere.
db.points.ensureIndex( { loc : "2dsphere" } );
For more information:
Index creation
Build a 2dsphere index
Geospatial indexes and queries

Is there a way to query for all locations (a list of polygons stored as geojson) fully covering given polygon with MongoDB?

I have a list of polygons stored as geoJson inside MongoDB.
Example of one of the polygons:
{
"Area" : "Area123",
"Boundary" : {
"type" : "Polygon",
"coordinates" : [[[100,12],[120,12],[120,15],[100,12]]]
}
}
Boundary is a 2dsphere index.
Using $geoWithin, I am able to specify a bigger polygon and return Area123 which lies fully within this bigger polygon.
Is there a way to specify a smaller polygon that lies within Area123 and let MongoDB returns Area123?
You can use $geoIntersects who specifically looks for polygon intersecting other ones. You can do something like this:
db.<collection>.find( { Boundary :
{ $geoIntersects :
{ $geometry :
{ type : "Polygon"
coordinates : [ <coordinates of Area123> ]
} } } } )
However this query will return even polygons who doesn't contains Area123 but also those who are inside, those who intersect a bit, etc.
So you can check if Area123 points, for each returned Polygon, are contained inside.

Use property for calculation in mongodb

specialists,
I have a document with several properties, one bein an lon/lat-array with a 2d index on it.
Another property is a radius property.
What I want:
{
geo:{
$within: { $center: [[ 9.078597000000036,50.580947], 1+radius]}
}
}
Is this available with mongodb? No matter what I am searching in google I am always directed to the mongodb documentation about geospatial indexes but my question is not getting answered.
Not sure if i understand you, but the docs page about geospatial indexes give a an example of a query like yours:
db.places.find( { geo: { $centerSphere: [ [long,lat ] ,
radius ] } } )
searches places collection for everything withing radius distance (in radians) from the point [long, lat].

how to deal with complicated query in mongodb?

I use mongodb to save the temporal and spatial data, and the document item is structured as follows:
doc = { time:t,
geo:[x,y]
}
If the different of two docs are defined as:
dist(doc1, doc2) = |t1-t2| + |x1-x2| + |y1 - y2|
How can I query the documents by mongodb and sort the results by their distance to a given document doc0 ={ time:t0, geo:[x0,y0] }?
thanks
Instead of calculating the distance manually, you could trust mongodb with that task. Mongodb has built in geospatial query support.
This would look like this:
db.docs.find( {
"time": "t0",
"geo" : { $near : [x0,y0] }
} ).limit(20)
The result would be all documents near the given location [x0,y0], automatically ordered by distance to that point.