Slide 1

Slide 1 text

Building your First MongoDB Application Rick Copeland @rick446 http://arborian.com Saturday, June 9, 12

Slide 2

Slide 2 text

Who am I? • Now a consultant, but formerly... • Software engineer at SourceForge • Author of Essential SQLAlchemy • Primarily code Python Saturday, June 9, 12

Slide 3

Slide 3 text

What will you learn here? Saturday, June 9, 12

Slide 4

Slide 4 text

What will you learn here? • Data Modeling Saturday, June 9, 12

Slide 5

Slide 5 text

What will you learn here? • Data Modeling • Queries Saturday, June 9, 12

Slide 6

Slide 6 text

What will you learn here? • Data Modeling • Queries • Geospatial indexing Saturday, June 9, 12

Slide 7

Slide 7 text

What will you learn here? • Data Modeling • Queries • Geospatial indexing • Updates Saturday, June 9, 12

Slide 8

Slide 8 text

What will you learn here? • Data Modeling • Queries • Geospatial indexing • Updates • Map/Reduce Saturday, June 9, 12

Slide 9

Slide 9 text

What will you learn here? • Data Modeling • Queries • Geospatial indexing • Updates • Map/Reduce • Deployment and Scaling Concerns Saturday, June 9, 12

Slide 10

Slide 10 text

What will you learn here? • Data Modeling • Queries • Geospatial indexing • Updates • Map/Reduce • Deployment and Scaling Concerns • Why MongoDB? Saturday, June 9, 12

Slide 11

Slide 11 text

Our Application • Users can create different locations • Users can “check in” to these locations • Users can see who else is checked in • Let’s call it ThreeTriangles (3tri) Saturday, June 9, 12

Slide 12

Slide 12 text

3tri Operations Places Checkins User-generated content Find nearby places Record checkins Checkin Stats Saturday, June 9, 12

Slide 13

Slide 13 text

MongoDB Terminology Relational MongoDB Database Database Table Collection Index Index Row Document Column Field Saturday, June 9, 12

Slide 14

Slide 14 text

Documents? doc1 = {! _id: ObjectId('4b97e62bf1d8c7152c9ccb74'), key1: value1,! key2: value2, key3: {..., ..., ...}, key4: [..., ..., ] } Saturday, June 9, 12

Slide 15

Slide 15 text

Collections • No schema enforcement • Per-collection... • Querying • Indexing • Updating • Sharding doc1,doc2,... doc5,doc6,... doc8,doc9,... Places Users Checkins Saturday, June 9, 12

Slide 16

Slide 16 text

Places v1 place1 = {! name: "Blake Hotel",! address: "555 South McDowell Street", city: "Charlotte", zip: "28204"} db.places.find({zip:"28204"}).limit(10) Saturday, June 9, 12

Slide 17

Slide 17 text

Places v2 place2 = { name: "Blake Hotel",! address: "555 South McDowell Street", city: "Charlotte", zip: "28204", tags: ["hotel", "recommended"]} db.places.find({ zip: "28204", tags: "hotel"}).limit(10) Saturday, June 9, 12

Slide 18

Slide 18 text

Places v3 place3 = { name: "Blake Hotel",! address: "555 South McDowell Street", city: "Charlotte", zip: "28204", tags: ["hotel", "recommended"], latlon: [ 35.21, 80.83 ] } db.places.ensureIndex({latlong:"2d"}) db.places.find({latlong:{$near:[35,80]}}) Saturday, June 9, 12

Slide 19

Slide 19 text

Places v4 place4 = { name: "Blake Hotel",! address: "555 South McDowell Street", city: "Charlotte", zip: "28204", tags: ["hotel", "recommended"], latlon: [ 35.21, 80.83 ], tips: [ { user: "rick", time: ISODateTime(...), tip: "Come learn about #self2012"}, { ... }, { ... } ] } Saturday, June 9, 12

Slide 20

Slide 20 text

Some Queries /* First, some indexes */ db.places.ensureIndex({tags:1}) db.places.ensureIndex({name:1}) db.places.ensureIndex({latlong:"2d"}) /* Find places */ db.places.find({latlong:{$near:[40,70]}}) /* Regex searching */ db.places.find({name: /^typeaheadstring/) /* Searching arrays */ db.places.find({tags: "business"}) Saturday, June 9, 12

Slide 21

Slide 21 text

Inserting and updating /* Initial data load */ db.places.insert([place1, place2, ...]) /* Update-in-place */ db.places.update( { name:"Blake Hotel" }, { $push : { tips: { user: "rick", time: ISODateTime(...), tip: "Come learn about #self2012" } } } ) Saturday, June 9, 12

Slide 22

Slide 22 text

3tri Operations Places Checkins User-generated content Find nearby places Record checkins Checkin Stats Saturday, June 9, 12

Slide 23

Slide 23 text

Users user1 = { name: "rick", email: "[email protected]", ... checkins: [ ObjectId('4b97e62bf1d8c7152c9ccb74'), ... ] } /* checkins [] = references checkin collection _id field */ Saturday, June 9, 12

Slide 24

Slide 24 text

Checkins db.checkins.ensureIndex({place:1, ts:1}) db.checkins.ensureIndex({ts:1}) checkin1 = { place: { id: ObjectId(...), name: "Blake Hotel" }, ts: ISODateTime(...), user: { id: ObjectId(...), name: "rick" } } Saturday, June 9, 12

Slide 25

Slide 25 text

Atomic Updates • $set • $unset • $rename • $push • $pushAll • $pop • $pull • $pullAll • $addToSet • $inc • $bit Saturday, June 9, 12

Slide 26

Slide 26 text

3tri Operations Places Checkins User-generated content Find nearby places Record checkins Checkin Stats Saturday, June 9, 12

Slide 27

Slide 27 text

Simple Statistics /* All checkins */ db.checkins.find({"place.name": "Blake Hotel"}) /* Last 10 checkins */ db.checkins.find({"place.name": "Blake Hotel"}) .sort({ts:-1}).limit(10) /* Number of checkins today */ db.checkins.find( { "place.name": "Blake Hotel", ts: { $gt: ISODateTime(...)} }) .count() Saturday, June 9, 12

Slide 28

Slide 28 text

MapReduce mapFunc = function() { emit(this.place.name, 1); } reduceFunc = function(key, values) { return Array.sum(values); } res = db.checkins.mapReduce( mapFunc, reduceFunc, ! { query: { ts: { $gt: nowminus3hrs } } out: {inline: 1} }) res.results = [ {_id:"Blake Hotel", value: 17}, ...] Saturday, June 9, 12

Slide 29

Slide 29 text

Deployment and Scaling Options Saturday, June 9, 12

Slide 30

Slide 30 text

Single Master Deployment Primary Secondary Secondary Read / Write Read Read Saturday, June 9, 12

Slide 31

Slide 31 text

Auto-Sharding Shard 1 (0..10) Primary Secondary Secondary Shard 2 (10..20) Primary Secondary Secondary Shard 3 (20..30) Primary Secondary Secondary Config Saturday, June 9, 12

Slide 32

Slide 32 text

Use Cases • Replace RDBMS for high-traffic web applications • CMS-style applications • Social and mobile applications • Real-time analytics, high-speed logging • Maybe not double-entry bookkeeping Saturday, June 9, 12

Slide 33

Slide 33 text

What do you give up? • No multi-document atomic operations (i.e. transactions) • No server-side JOINs • No referential integrity constraints between documents • Data model is typically tied to query patterns (less flexible than relational DBs) Saturday, June 9, 12

Slide 34

Slide 34 text

Questions? Please rate this talk at http://svy.mk/L3jM7f Interested in training? http://Arborian.com/training MongoDB Info & Downloads: http://mongodb.org Rick Copeland @rick446 http://arborian.com Saturday, June 9, 12