I’m working on a mobile app that tracks a user’s location at regular intervals to allow him to plot the path of a journey on a map. We’d like to add an optional feature that will tell him what other users of the app have made similar journeys in the timeframe he’s looking at, be it today’s commute or the last month of travel. We’re referring to this as “path-matching”.
The data is currently logged into files within the app’s private storage directories on iOS and Android in a binary format that is easily and quickly scanned through to read locations. Each file contains the locations for one day, and generally runs to about 80KB.
To be able to implement the path matching feature we’ll obviously need to start uploading these location logs to our server (with the users permission of course), on which we’re running PHP. Someone suggested MongoDB for its geospatial prowess – but I’ve a few questions that maybe folks could help me with:
-
It seems like we could change our location-logging to use BSON instead. The first field would be a device or user IDs, followed by a list of locations for a particular day. The file could then be uploaded to our server and pushed into the MongoDB store. The online documentation however only seems to refer to importing BSON files created by mongodump. Is the format stable enough that any app could write BSON files readable directly by MongoDB?
-
Is MongoDB able to run geospatial queries on documents containing multiple locations, or on locations forming a path across multiple documents? Or does this strike you as something that would require excessive logic outside the database, on the PHP side?
The format is totally stable, but there isn’t much tooling to do what you describe. Generally, you’d upload it to the backend and it would end up in, say
$_POST['locations']or something that would be an array of associative arrays. Sanitize it and just save it to the database, something like:$locs = sanitize($_POST[‘locations’]);
$doc = array(‘path’ => array(‘type’ => ‘LineString’, ‘coordinates’ => $locs), ‘user’ => $userId);
$collection->insert($doc);
In the above example, I’m using some of the latest geo stuff (http://docs.mongodb.org/manual/release-notes/2.4/#new-geospatial-indexes-with-geojson-and-improved-spherical-geometry), you’ll need a nightly build to get this but it should be in the stable build in about a month. If you need it before then, you can use the older geo API: http://docs.mongodb.org/manual/core/geospatial-indexes/.
MongoDB doesn’t read BSON files, but you could use mongorestore to manually load them. I would highly recommend letting the driver do the low-level stuff for you, though!
You can have a document containing a line (in the new geo stuff) and an array of points (in the old geo stuff). I’m not sure what you mean by “a path across multiple documents.”
Edited to add: based on your comment, you might want to try
{path : {$near : {$geometry : userPath}}}to find “nearby” paths. You could also try making a polygon around the user’s path and querying for docs $within the polygon.