How to pull data from mongodb? - mongodb

I built a location-aware web application and used the W3C Geolocation API for detecting the location of a visitor and used the Google Maps API to display the map. How can I get data stored in mongodb that represent information about places near me to display above a place when click it on the map?
for example:
db.places.insert({name:"",kind:"restaurant",serves:["Fast food","Sea food"],price:{fast food:200$,Sea food:175$}});
I want these information displayed when I click a restaurant on map.
When I click a restaurant's name on the map, I want to display these information above the restaurant's name.

Well, to start, you're gonna want to associate the restaurants with geo location data. If you have lat lon stored, then you can query using mongodb Geospatial queries:
http://docs.mongodb.org/manual/reference/operator/query-geospatial/
Here is a sample from the docs:
db.places.find( { loc : { $near :
{ $geometry :
{ type : "Point" ,
coordinates: [ 40 , 5 ] } },
$maxDistance : 500
} } )

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.

mongodb and geospatial schema

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 ]
}
}
}
}
)

How do I set up a geospatial 2dsphere index on field that is an array?

I am trying to use geospatial 2dsphere on an field that is an array of coordinates.
I have cities with areas and each city has its own array of areas. When I try to do an intersection, i test myArea only with the areas of a particular city. Thus, I don't want to put ALL AREAS from all cities in the same collection.
Thus my question, how do you set this up?
My server is nodejs and i use native mongodb lib, if it helps.
GeoJSON does define a MultiPoli datatype, which has been implemented in recent releases of MongoDB. If you can't use one of these versions, you can workaround, by creating a document for each city in one collection, and a document for each Polygon associated to a city in another collection while storing the id of the original city.
i.e.
city Collection:
{
_id: ObjectId("51f67cfb20ea59dba539d9f8"),
name: 'New York',
...
}
city_polys Collection
{
city_id: ObjectId("51f67cfb20ea59dba539d9f8"),
loc: {
type: Polygon,
coordinates: ...
},
...
}
You can then create a 2dsphere index on the city_poly's loc field.

Updating MongoDB document for geospatial searching

Currently, I have my lat/long in separate fields in my MongoDB database, but if I want to do geospatial searching I need to have them in this format:
{ location : [ 50 , 30 ] }
By what means can I transpose the values of my lat/long keys into a new key per document as per above?
TIA!
You will have to iterate through all your documents that don't have a location field and add it (presumably deleting the lat/long fields unless this will break your application).
db.mycollection.find( { location : { $exists : false } } ).forEach(
function (doc) {
// Add (lon, lat) pairs .. order is important
doc.location = { lon: doc.lon, lat: doc.lat };
// Remove old properties
delete doc.lon;
delete doc.lat;
// Save the updated document
db.mycollection.save(doc);
}
)
Note that the order for MongoDB geospatial indexing should be consistent in your document as (longitude, latitude).

Mongo DB Design For Events Calendar

We have an events calendar and here is what I am thinking for our basic mongo schema:
users
username
password
salt
events
name
description
tags[]
category
venue_id
...
venues
name
address
loc
Queries that will be done are:
Listing of distinct tags (this might be hard given current design)
events in a given tag
Event information along with the venue location
All event and venue information for a particular event
All events near me. Need to use a geo index on loc
Any feedback/ideas on if we should be nesting venues inside events or use mysql instead?
Ok, that looks pretty good. Let's construct some of the queries.
Assuming the collections are named users, events, venues:
Insert some dummy events:
db.events.insert({tags:["awesome","fun","cool"]})
db.events.insert({tags:["sweet","fun","rad"]})
Make an index (like a boss)
db.events.ensureIndex({ tags: 1 })
Listing of distinct tags (this might be hard given current design):
Nope, not hard.
db.events.distinct("tags")
[ "awesome", "cool", "fun", "rad", "sweet" ]
Events in a given tag (you meant "with a given tag" right?)
db.events.find({tags: "fun"})
{ "_id" : ObjectId("4ecc08c62477605df6522c97"), "tags" : [ "awesome", "fun", "cool" ] }
{ "_id" : ObjectId("4ecc08d92477605df6522c98"), "tags" : [ "sweet", "fun", "rad" ] }
Event information along with venue location
You can do this a couple different ways. One way would be to query for the event and subsequently query for the venue. With both documents, join (combine) the data you want manually.
OR
You can denormalize a bit and store cached venue names + locations (but not venue details like hours of operation, max occupancy, website, phone number, etc..) for a speed boost (1 query instead of 2) That method comes with the standard denormalization caveat of not being able to update your data in one place.
All event and venue information for a particular event
See above
All events near me. Need to use a geo index on loc
Two queries again, same concept as above just reverse the order.
Get the venues:
db.venues.find( { loc : { $near : [lat,lon] } } )
Get the events using the venue ids:
db.events.find( { venue : { $in : [id1,id2,id3...] } } )
Some of this stuff can be done automatically for you if you use an ODM.
Good luck!