Your SlideShare is downloading. ×
0
Building Apps With


Nate Abele
IPC — 1 June 2010
Berlin
X
Me


Former lead developer, CakePHP
Lead developer, Lithium
Twitter: @nateabele
“Alternative” databases?
What’s the point?

 Relational databases » relational algebra » set theory
 ORM “impedance mismat...
What’s a document database?


Composed of documents ...duh
Each document is heterogenous, and may have a
completely unique...
Why Mongo?

                   .org :

“The best features of document databases,
key-value stores, and relational database...
Mongo is...


 Fast
 Smart
 Scalable
Terminology


Database   »   Database

Table      »   Collection

Row        »   Document
Common Tasks
       tags
  id
                        MySQL
  name


   posts_tags
  id                    posts    commen...
Common Tasks       id
                           posts

                   title
                   slug
         MongoDB ...
Common Tasks
MongoDB
{
    "_id" : ObjectId("4c03e856e258c2701930c091"),
    "title" : "Welcome to MongoDB",
    "slug" : ...
[...frantic hand-wringing ensues...]
[...pause, deep breath...]
Doing the “normal db” stuff
How do I...

 ...do pattern-matching?
 db.posts.find({ "title" : /mongodb/i })


 ...find all p...
Doing the “normal db” stuff
How do I...



 ...change Bob’s email?
 db.posts.update(
     { "comments.email": "bob@example...
$set?
Querying
$gt     $all
$gte	   $size
$lt	    $exists
$lte	   $type
$ne	    $elemMatch
$in	    $not
$nin	   $where
$mod
Querying
dontTrust = db.people.find({
  “age”: { $gt : 30 }
})
awesome = db.posts.find({ “tags” : {
  $in : [‘MongoDB’, ‘a...
Querying
By arbitrary function:
db.posts.find({ $where: function() {
    return this.hits % 2 == 0;
}})

By grouping key:
...
Querying
By grouping function:
db.photos.group({
  keyf: function(o) {
     return {
       hits: Math.round(o.hits / 1000...
Grouping results
[
    { 'hits' => 0, 'count' => 5 },
    { 'hits' => 1, 'count' => 4 },
    { 'hits' => 2, 'count' => 7 }...
Map/reduce


...with apologies to John Nunemaker.
Map/reduce
>   db.items.insert({tags:   ['dog', 'cat']})
>   db.items.insert({tags:   ['dog']})
>   db.items.insert({tags:...
Map/reduce
> var map = function() {
    this.tags.forEach(function(t) {
      emit(t, {count: 1});
    });
}
Map/reduce
> var reduce = function(key, val) {
  var count = 0;
  for(var i = 0, len = val.length; i < len; i++) {
    cou...
Map/reduce


> var result = db.items.mapReduce(map, reduce);
Map/reduce
{
    "ok" : 1,
    "timeMillis" : 86,
    "result" : "tmp.mr.mapreduce_1273861517_683",
    "counts" : {
     ...
Map/reduce
db["tmp.mr.mapreduce_1273861517_683"].find()


{   "_id"   :   "cat",	"value" :   {   "count" :   1   }   }
{  ...
Atomic Operations

Incrementing & decrementing: $inc:
  db.posts.update(
    { _id : new ObjectId("4c041e...30c093") },
  ...
Atomic Operations


Adding, updating & removing: $set & $unset:
 db.posts.update({}, { $set : { "hits" : 0 }})

 db.posts....
Atomic Operations

Array operations: $push[All], $pull[All],
$addToSet & $pop:

 db.posts.update({ "tags": "MongoDB" }, {
...
Atomic Operations
Array operations: $push[All], $pull[All],
$addToSet & $pop:

 db.queues.update(
   { _id : new ObjectId(...
Indexes


Slows write performance, but greatly improves reads
For best results, index on what you query on
Mongo likes to ...
Indexes

db.users.ensureIndex({ “email”: 1 })
db.posts.ensureIndex({ “tags”: 1 })
db.posts.ensureIndex({ “created”: -1 })
...
Indexes

“unique” / “dropDups”: ensure uniqueness
“safe”: Make sure it worked. Else, panic.
“name”: Mostly for troubleshoo...
Indexes
When in doubt, explain()
{   "cursor" : "BtreeCursor hits_1 multi",
    "indexBounds" : [
       [{ "hits" : 0 }, ...
Location, location, location
Location
MongoDB makes location-aware apps stupid-simple
First, add an index:

db.places.ensureIndex({ location: “2d” })
G...
Location
Location

db.places.find({
   location: { $within : { $box : {
   [
     [40.800788494123154,
      -73.85556051757814],
 ...
Easy to get started
 Up and running on most systems in a half-dozen
 commands or less fewer
 http://try.mongodb.org/
Coming to a platform near you
Drupal for MongoDB
http://drupal.org/project/mongodb

D7: mongodb_cache: Store cache items in mongodb

D7: mongodb_field_st...
Even MORE Drupal

Work to get listing API into core:
http://drupal.org/node/780154
Experimental goodies to play with:
http...
Joomla!


MongoDB helper library for Joomla!
Branch of 1.6 development for alternative query builder
Full MongoDB support ...
Lithium PHP framework

MongoDB native support since 0.2
http://rad-dev.org/lithium/wiki
Projects demonstrating MongoDB sup...
CakePHP framework

MongoDB datasource
http://github.com/ichikaway/mongoDB-Datasource
Example article
http://mark-story.com...
MongoDB Language Center
http://www.mongodb.org/display/DOCS/Drivers
Community Resources
http://www.mongodb.org/display/DOCS/
Community
Development Tracker
http://jira.mongodb.org
MongoDB Cookbook
http://cookbook.mongodb.org/
Thanks!
{
    email:    “nate.abele@gmail.com”,
    twitter: “@nateabele”,
    web:      “http://lithify.me/”,
    slides:...
Building Apps with MongoDB
Upcoming SlideShare
Loading in...5
×

Building Apps with MongoDB

27,514

Published on

Relational databases are central to web applications, but they have also been the primary source of pain when it comes to scale and performance. Recently, non-relational databases (also referred to as NoSQL) have arrived on the scene. This session explains not only what MongoDB is and how it works, but when and how to gain the most benefit.

Published in: Technology
1 Comment
100 Likes
Statistics
Notes
  • slide 10 and 11 did so much more to explain MongoDB in 3 seconds than homepages, articles of advantages, stackoverflow posts did...
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
27,514
On Slideshare
0
From Embeds
0
Number of Embeds
24
Actions
Shares
0
Downloads
1,309
Comments
1
Likes
100
Embeds 0
No embeds

No notes for slide

Transcript of "Building Apps with MongoDB"

  1. 1. Building Apps With Nate Abele IPC — 1 June 2010 Berlin
  2. 2. X
  3. 3. Me Former lead developer, CakePHP Lead developer, Lithium Twitter: @nateabele
  4. 4. “Alternative” databases? What’s the point? Relational databases » relational algebra » set theory ORM “impedance mismatch” Failed alternatives reinforced the status quo
  5. 5. What’s a document database? Composed of documents ...duh Each document is heterogenous, and may have a completely unique structure compared to other documents ...That’s pretty much it
  6. 6. Why Mongo? .org : “The best features of document databases, key-value stores, and relational databases.”
  7. 7. Mongo is... Fast Smart Scalable
  8. 8. Terminology Database » Database Table » Collection Row » Document
  9. 9. Common Tasks tags id MySQL name posts_tags id posts comments post_id id id tag_id title post_id slug author body email published body created created updated
  10. 10. Common Tasks id posts title slug MongoDB body published created updated comments author email body created tags
  11. 11. Common Tasks MongoDB { "_id" : ObjectId("4c03e856e258c2701930c091"), "title" : "Welcome to MongoDB", "slug" : "welcome-to-mongodb", "body" : "Today, we're gonna totally rock your world...", "published" : true, "created" : "Mon May 31 2010 12:48:22 GMT-0400 (EDT)", "updated" : "Mon May 31 2010 12:48:22 GMT-0400 (EDT)", "comments" : [ { "author" : "Bob", "email" : "bob@example.com", "body" : "My mind has been totally blown!", "created" : "Mon May 31 2010 12:48:22 GMT-0400 (EDT)" } ], "tags" : [ "databases", "MongoDB", "awesome" ] }
  12. 12. [...frantic hand-wringing ensues...]
  13. 13. [...pause, deep breath...]
  14. 14. Doing the “normal db” stuff How do I... ...do pattern-matching? db.posts.find({ "title" : /mongodb/i }) ...find all posts tagged ‘MongoDB’? db.posts.find({ "tags" : "MongoDB" }) ...find all Bob’s comments? db.posts.find({ "comments.email" : "bob@example.com" })
  15. 15. Doing the “normal db” stuff How do I... ...change Bob’s email? db.posts.update( { "comments.email": "bob@example.com" }, { $set : { "comments.$.email" : "robert@example.com" }} )
  16. 16. $set?
  17. 17. Querying $gt $all $gte $size $lt $exists $lte $type $ne $elemMatch $in $not $nin $where $mod
  18. 18. Querying dontTrust = db.people.find({ “age”: { $gt : 30 } }) awesome = db.posts.find({ “tags” : { $in : [‘MongoDB’, ‘awesome’] }}) todo = db.tasks.find({ “status” : { $nin : [ ‘In Progress’, ‘Completed‘ ]} })
  19. 19. Querying By arbitrary function: db.posts.find({ $where: function() { return this.hits % 2 == 0; }}) By grouping key: db.posts.group({ "key": { "hits": true }, "initial": { count: 0 }, "reduce": function(obj, prev) { prev.count++; } });
  20. 20. Querying By grouping function: db.photos.group({ keyf: function(o) { return { hits: Math.round(o.hits / 1000) }; }, "initial": { count: 0 }, "reduce": function(obj, prev) { prev.count++; } });
  21. 21. Grouping results [ { 'hits' => 0, 'count' => 5 }, { 'hits' => 1, 'count' => 4 }, { 'hits' => 2, 'count' => 7 }, ... ]
  22. 22. Map/reduce ...with apologies to John Nunemaker.
  23. 23. Map/reduce > db.items.insert({tags: ['dog', 'cat']}) > db.items.insert({tags: ['dog']}) > db.items.insert({tags: ['dog', 'mouse']}) > db.items.insert({tags: ['dog', 'mouse', 'hippo']}) > db.items.insert({tags: ['dog', 'mouse', 'hippo']}) > db.items.insert({tags: ['dog', 'hippo']})
  24. 24. Map/reduce > var map = function() { this.tags.forEach(function(t) { emit(t, {count: 1}); }); }
  25. 25. Map/reduce > var reduce = function(key, val) { var count = 0; for(var i = 0, len = val.length; i < len; i++) { count += val[i].count; } return { count: count }; }
  26. 26. Map/reduce > var result = db.items.mapReduce(map, reduce);
  27. 27. Map/reduce { "ok" : 1, "timeMillis" : 86, "result" : "tmp.mr.mapreduce_1273861517_683", "counts" : { "input" : 6, "emit" : 13, "output" : 4 } }
  28. 28. Map/reduce db["tmp.mr.mapreduce_1273861517_683"].find() { "_id" : "cat", "value" : { "count" : 1 } } { "_id" : "dog", "value" : { "count" : 6 } } { "_id" : "hippo", "value" : { "count" : 3 } } { "_id" : "mouse", "value" : { "count" : 3 } }
  29. 29. Atomic Operations Incrementing & decrementing: $inc: db.posts.update( { _id : new ObjectId("4c041e...30c093") }, { $inc : { "hits" : 1 }} ) db.posts.update( { _id : new ObjectId("4c041e...30c093") }, { $inc : { "hits" : -1 }} )
  30. 30. Atomic Operations Adding, updating & removing: $set & $unset: db.posts.update({}, { $set : { "hits" : 0 }}) db.posts.update({}, { $unset : { "hits" : 1 }})
  31. 31. Atomic Operations Array operations: $push[All], $pull[All], $addToSet & $pop: db.posts.update({ "tags": "MongoDB" }, { $push: { "tags" : "awesome" } }) db.posts.update({ "tags": "MySQL" }, { $pull: { "tags" : "awesome" } })
  32. 32. Atomic Operations Array operations: $push[All], $pull[All], $addToSet & $pop: db.queues.update( { _id : new ObjectId("4c041e...30c093") }, { $pop: { "operations" : 1 }} ) db.todos.update( { _id : new ObjectId("4c041e...30c093") }, { $pop: { "listItems" : -1 }} )
  33. 33. Indexes Slows write performance, but greatly improves reads For best results, index on what you query on Mongo likes to fit its indexes in memory
  34. 34. Indexes db.users.ensureIndex({ “email”: 1 }) db.posts.ensureIndex({ “tags”: 1 }) db.posts.ensureIndex({ “created”: -1 }) db.posts.ensureIndex({ “tags”: 1, “created”: -1 })
  35. 35. Indexes “unique” / “dropDups”: ensure uniqueness “safe”: Make sure it worked. Else, panic. “name”: Mostly for troubleshooting “background”: Best. Performance. Panic. Button. Ever.
  36. 36. Indexes When in doubt, explain() { "cursor" : "BtreeCursor hits_1 multi", "indexBounds" : [ [{ "hits" : 0 }, { "hits" : 0 }], [{ "hits" : 1 }, { "hits" : 1 }] ], "nscanned" : 1, "nscannedObjects" : 1, "n" : 1, "millis" : 35, "allPlans" : [ { "cursor" : "BtreeCursor hits_1 multi", "indexBounds" : [ [{ "hits" : 0 }, { "hits" : 0 }], [{ "hits" : 1 }, { "hits" : 1 }] ] } ] }
  37. 37. Location, location, location
  38. 38. Location MongoDB makes location-aware apps stupid-simple First, add an index: db.places.ensureIndex({ location: “2d” }) Go to town: db.places.find({ location: { $near : [ 40.79870933724115, -73.7656099560547 ]} })
  39. 39. Location
  40. 40. Location db.places.find({ location: { $within : { $box : { [ [40.800788494123154, -73.85556051757814], [40.68008976560161, -74.04232809570314] ] });
  41. 41. Easy to get started Up and running on most systems in a half-dozen commands or less fewer http://try.mongodb.org/
  42. 42. Coming to a platform near you
  43. 43. Drupal for MongoDB http://drupal.org/project/mongodb D7: mongodb_cache: Store cache items in mongodb D7: mongodb_field_storage: Store the fields in mongodb D7: mongodb_session: Store sessions in mongodb D6/D7: mongodb_watchdog: Store the watchdog messages in mongodb D6/D7: mongodb: support library for the other modules D7: mongodb_block: Store block information in mongodb. Very close to the core block API D7: mongodb_queue: DrupalQueueInterface implementation using mongodb http://sf2010.drupal.org/conference/sessions/mongodb-humongous-drupal
  44. 44. Even MORE Drupal Work to get listing API into core: http://drupal.org/node/780154 Experimental goodies to play with: http://drupalcode.org/viewvc/drupal/contributions/ sandbox/chx/dbtng_mongo_experimental/
  45. 45. Joomla! MongoDB helper library for Joomla! Branch of 1.6 development for alternative query builder Full MongoDB support most likely in 2.0
  46. 46. Lithium PHP framework MongoDB native support since 0.2 http://rad-dev.org/lithium/wiki Projects demonstrating MongoDB support: http://rad-dev.org/lithium_mongo/source http://rad-dev.org/lithium_blog/source
  47. 47. CakePHP framework MongoDB datasource http://github.com/ichikaway/mongoDB-Datasource Example article http://mark-story.com/posts/view/using-mongodb- with-cakephp
  48. 48. MongoDB Language Center http://www.mongodb.org/display/DOCS/Drivers
  49. 49. Community Resources http://www.mongodb.org/display/DOCS/ Community
  50. 50. Development Tracker http://jira.mongodb.org
  51. 51. MongoDB Cookbook http://cookbook.mongodb.org/
  52. 52. Thanks! { email: “nate.abele@gmail.com”, twitter: “@nateabele”, web: “http://lithify.me/”, slides: “http://www.slideshare.net/nateabele” }
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×