53
Building Apps With Nate Abele IPC — 1 June 2010 Berlin

Building Apps with MongoDB

Embed Size (px)

DESCRIPTION

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.

Citation preview

Page 1: Building Apps with MongoDB

Building Apps With

Nate Abele

IPC — 1 June 2010

Berlin

Page 2: Building Apps with MongoDB
Page 3: Building Apps with MongoDB

X

Page 4: Building Apps with MongoDB

Me

Former lead developer, CakePHP

Lead developer, Lithium

Twitter: @nateabele

Page 5: Building Apps with MongoDB

“Alternative” databases? What’s the point?

Relational databases » relational algebra » set theory

ORM “impedance mismatch”

Failed alternatives reinforced the status quo

Page 6: Building Apps with MongoDB

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

Page 7: Building Apps with MongoDB

Why Mongo?

.org :

“The best features of document databases,key-value stores, and relational databases.”

Page 8: Building Apps with MongoDB

Mongo is...

Fast

Smart

Scalable

Page 9: Building Apps with MongoDB

Terminology

Database » Database

Table » Collection

Row » Document

Page 10: Building Apps with MongoDB

Common Tasks

postsidtitleslugbodypublishedcreatedupdated

commentsidpost_idauthoremailbodycreated

posts_tagsidpost_idtag_id

tagsidname

MySQL

Page 11: Building Apps with MongoDB

Common Tasks

MongoDB

postsidtitleslugbodypublishedcreatedupdated

commentsauthoremailbodycreated

tags

Page 12: Building Apps with MongoDB

Common TasksMongoDB

{ "_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" : "[email protected]", "body" : "My mind has been totally blown!", "created" : "Mon May 31 2010 12:48:22 GMT-0400 (EDT)" } ], "tags" : [ "databases", "MongoDB", "awesome" ]}

Page 13: Building Apps with MongoDB

[...frantic hand-wringing ensues...]

Page 14: Building Apps with MongoDB

[...pause, deep breath...]

Page 15: Building Apps with MongoDB

Doing the “normal db” stuff

...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" : "[email protected]" })

How do I...

Page 16: Building Apps with MongoDB

Doing the “normal db” stuff

...change Bob’s email?db.posts.update(

{ "comments.email": "[email protected]" },

{ $set : { "comments.$.email" : "[email protected]" }})

How do I...

Page 17: Building Apps with MongoDB

$set?

Page 18: Building Apps with MongoDB

Querying$gt $all$gte $size$lt $exists $lte $type$ne $elemMatch $in $not$nin $where$mod

Page 19: Building Apps with MongoDB

QueryingdontTrust = db.people.find({ “age”: { $gt : 30 }})

awesome = db.posts.find({ “tags” : { $in : [‘MongoDB’, ‘awesome’]}})

todo = db.tasks.find({ “status” : { $nin : [ ‘In Progress’, ‘Completed‘ ]}})

Page 20: Building Apps with MongoDB

QueryingBy 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++; }});

Page 21: Building Apps with MongoDB

QueryingBy grouping function:db.photos.group({ keyf: function(o) { return { hits: Math.round(o.hits / 1000) }; }, "initial": { count: 0 }, "reduce": function(obj, prev) { prev.count++; }});

Page 22: Building Apps with MongoDB

Grouping results[ { 'hits' => 0, 'count' => 5 }, { 'hits' => 1, 'count' => 4 }, { 'hits' => 2, 'count' => 7 }, ...]

Page 23: Building Apps with MongoDB

Map/reduce

...with apologies to John Nunemaker.

Page 24: Building Apps with MongoDB

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

Page 25: Building Apps with MongoDB

Map/reduce

> var map = function() { this.tags.forEach(function(t) { emit(t, {count: 1}); });}

Page 26: Building Apps with MongoDB

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 };}

Page 27: Building Apps with MongoDB

Map/reduce

> var result = db.items.mapReduce(map, reduce);

Page 28: Building Apps with MongoDB

Map/reduce{ "ok" : 1, "timeMillis" : 86, "result" : "tmp.mr.mapreduce_1273861517_683", "counts" : { "input" : 6, "emit" : 13, "output" : 4 }}

Page 29: Building Apps with MongoDB

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

Page 30: Building Apps with MongoDB

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

Page 31: Building Apps with MongoDB

Atomic Operations

Adding, updating & removing: $set & $unset:

db.posts.update({}, { $set : { "hits" : 0 }})

db.posts.update({}, { $unset : { "hits" : 1 }})

Page 32: Building Apps with MongoDB

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

Page 33: Building Apps with MongoDB

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

Page 34: Building Apps with MongoDB

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

Page 35: Building Apps with MongoDB

Indexes

db.users.ensureIndex({ “email”: 1 })

db.posts.ensureIndex({ “tags”: 1 })

db.posts.ensureIndex({ “created”: -1 })

db.posts.ensureIndex({ “tags”: 1, “created”: -1})

Page 36: Building Apps with MongoDB

Indexes

“unique” / “dropDups”: ensure uniqueness

“safe”: Make sure it worked. Else, panic.

“name”: Mostly for troubleshooting

“background”: Best. Performance. Panic. Button. Ever.

Page 37: Building Apps with MongoDB

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

Page 38: Building Apps with MongoDB

Location, location, location

Page 39: Building Apps with MongoDB

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

Page 40: Building Apps with MongoDB

Location

Page 41: Building Apps with MongoDB

Location

db.places.find({ location: { $within : { $box : { [ [40.800788494123154, -73.85556051757814], [40.68008976560161, -74.04232809570314] ]});

Page 42: Building Apps with MongoDB

Easy to get startedUp and running on most systems in a half-dozen commands or less fewer

http://try.mongodb.org/

Page 43: Building Apps with MongoDB

Coming to a platform near you

Page 44: Building Apps with MongoDB

Drupal for MongoDBhttp://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

Page 46: Building Apps with MongoDB

Joomla!

MongoDB helper library for Joomla!

Branch of 1.6 development for alternative query builder

Full MongoDB support most likely in 2.0

Page 47: Building Apps with MongoDB

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

Page 49: Building Apps with MongoDB

MongoDB Language Centerhttp://www.mongodb.org/display/DOCS/Drivers

Page 51: Building Apps with MongoDB

Development Trackerhttp://jira.mongodb.org

Page 52: Building Apps with MongoDB

MongoDB Cookbookhttp://cookbook.mongodb.org/

Page 53: Building Apps with MongoDB

Thanks!

{

email: “[email protected]”,

twitter: “@nateabele”,

web: “http://lithify.me/”,

slides: “http://www.slideshare.net/nateabele”

}