InfoWorld: Use MongoDB to make your app location-aware

Crunching contextual data about users can sell more stuff -- and in a mobile world, location data rules. Here's how to add location awareness to mobile apps with MongoDB

The surging popularity of Hadoop has paved the way to storing and processing gobs of semistructured data. Batch processing data is a great way to study the past in high definition, but it's constrained by the simple phrase "next time." As in: "Looks like our customers didn't like the way the checkout process went, let's change that for next time."

Constructing a "this time" solution can be approached in several ways. One angle of attack is to combine batch and real-time analytics: Set up MapReduce jobs to run every night, for example, and pipe the results into a NoSQL database to be queried throughout the day. MapReduce distills and condenses the data set, allowing it to be accessed quickly as needed.

Another approach is to focus on the state of the user at the current moment. In other words, context -- not what will be, but what is, right now. And particularly for mobile applications, what information could be more important about the user's state than his or her geolocation?

Location awareness is an idea that's spreading both inside the tech world and out (just think about the locavore or farm-to-table trends in the foodie community). GPS-enabled mobile devices have been a boon to developers and technology providers paying attention to these trends. One such provider is our new favorite billion-dollar NoSQL company, MongoDB.

MongoDB's new geospatial query in action
MongoDB has had native geospatial queries for a while (famously used by Foursquare), which make finding documents that are near a given point or documents that lie within a given polygon a breeze.

The latest production release introduced a new query operator: $geoIntersects. The operator packs quite a punch, filling in functionality lacking in previous versions. For example, if you wanted to supply a point and find all the documents enclosing that point, you had to do it on your application layer. If you wanted to supply a polygon and see which documents overlap, you had to do it on your application layer. If you wanted to supply a line and see which documents could be found on that line, you did it in your application layer.

Happily, $geoIntersects does all that and more. On top of the flexibility, it's incredibly easy to use. The general idea is that you can supply a point, line, or polygon, and any document that intersects with the supplied geometry will be returned. To demonstrate, I've built a little Web app that relies on the query.

The app takes a starting and ending address, finds a bike route for the supplied points, and tells you all the Chicago neighborhoods you'd pass through. It will also tell you which Chicago neighborhood you're in at the moment. The app is simple, but shows two possible uses of the new query operator. Here's what it looks like:

TEXT

To start, I pulled all the neighborhood boundary data from the city of Chicago's website. After a quick conversion to GeoJSON, I imported the data into a collection in MongoDB namedneighborhoods. Each neighborhood document looks roughly like this:

{

"_id" : ObjectId("5265a131089bf0213b4c307c"),

"type" : "Feature",

"properties" : {

"PRI_NEIGH" : "West Loop",

...

},

"geometry" : {

"type" : "Polygon",

"coordinates" : [

[

[

-87.64446845179363,

41.85995449225369

],

...

]

}

}

While some geospatial queries in MongoDB require a geospatial index, $geoIntersects does not. That said, it's smart and easy to add indexes for common queries, so I did.

Now the query itself is trivially simple. To find out which neighborhood I'm in, I'll build a query like this:

db.neighborhoods.find({

geometry: {

$geoIntersects : {

$geometry: {

type: "Point",

coordinates: [ lng, lat ]

}

}

}

});

What does it look like if I query for all the neighborhoods that my bike route passes through?

db.neighborhoods.find({

geometry: {

$geoIntersects : {

$geometry: {

type: "LineString",

coordinates: [ [ lng0, lat0], [ lng1, lat1 ], [ lng2, lat2], ... ]

}

}

}

});

It's almost exactly the same and produces the results we want.

The whole process to download, convert, import, and query this information took less than an hour, leaving me the rest of the day to build up a simple back end and work on the UI. This sort of development speed is powerful, enabling quick prototyping and experimentation at low cost.

The app I've built is obviously geocentric in order to clearly outline some of the possibilities of this new query. When it comes to contextualizing your user experience, however, you don't have to make it this obvious. In fact, you probably won't want to. One of the most powerful aspects of a contextualized experience is that the lines blur between your app and the other aspects of the user's life. An example of this is in iOS 7, where, based on your current location and location history, you'll find out how long it will take to get to your next likely destination in the notification center.

With these sorts of great tools at your disposal, it's time to explore the possibility of incorporating into your application. There's a low cost of experimentation, and the potential for finding interesting and beneficial applications of the technology is high. So play around with it a little and see what happens, your customers (and your bottom line) will be happier for it.

The source code for the app is available on GitHub, and a running version of the app can be found here.

This article was originally published at InfoWorld.com. Check out this article and more from the Strategic Developer blog every Thursday!

Comments

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
Are you for real?
Image CAPTCHA
Enter the characters shown in the image.