PHP Loves MongoDB - Dublin MUG (by Hannes)

2,508
-1

Published on

Hannes (not me) presents on "PHP & MongoDB" at the Dublin MUG (15/08/12), @ EngineYard.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,508
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
47
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

PHP Loves MongoDB - Dublin MUG (by Hannes)

  1. 1. 1 PHP ♥ MongoDB Saturday 18 August 2012
  2. 2. • Hannes / @bjori • Icelandic » Oslo, Norway » London, England • PHP Driver Engineer » @10gen • PHP Contributor About me 2 Saturday 18 August 2012
  3. 3. Why I started with MongoDB • Like creating (code, not graphics) • Productivity • Don’t want to waste my time 3 Saturday 18 August 2012
  4. 4. The “old” way 4 Saturday 18 August 2012
  5. 5. The “new” way 5 Saturday 18 August 2012
  6. 6. Terminology RDBMS Mongo Table, View ➜ Collection Row ➜ JSON Document Index ➜ Index Join ➜ Embedded Document Partition ➜ Shard Partition Key ➜ Shard Key 6 Saturday 18 August 2012
  7. 7. PostObject Object( [title] => MongoDB [contributors] => Array( [0] => PersonObject Object( [name] => Eliot Horowitz [email] => eh@10gen.com ) [1] => PersonObject Object( [name] => Dwight Merriman [email] => dm@10gen.com ) ) [model] => ModelObject Object( [relational] => [awesome] => 1 ) ) Tables to Documents { title: ‘MongoDB’, contributors: [ { name: ‘Eliot Horowitz’, email: ‘eh@10gen.com’ }, { name: ‘Dwight Merriman’, email: ‘dm@10gen.com’ } ], model: { relational: false, awesome: true } } Documents to Arrays Documents to Objects 7 Saturday 18 August 2012
  8. 8. PostObject Object( [title] => MongoDB [contributors] => Array( [0] => PersonObject Object( [name] => Eliot Horowitz [email] => eh@10gen.com ) [1] => PersonObject Object( [name] => Dwight Merriman [email] => dm@10gen.com ) ) [model] => ModelObject Object( [relational] => [awesome] => 1 ) ) array( "title" => 'MongoDB', "contributors" => array( array( 'name' => 'Eliot Horowitz', 'email' => 'eh@10gen.com' ), array( 'name' => 'Dwight Merriman', 'email' => 'dm@10gen.com' ) ), "model" => array( 'relational' => false, 'awesome' => true Tables to Documents { title: ‘MongoDB’, contributors: [ { name: ‘Eliot Horowitz’, email: ‘eh@10gen.com’ }, { name: ‘Dwight Merriman’, email: ‘dm@10gen.com’ } ], model: { relational: false, awesome: true } } Documents to Arrays Documents to Objects 7 Saturday 18 August 2012
  9. 9. PostObject Object( [title] => MongoDB [contributors] => Array( [0] => PersonObject Object( [name] => Eliot Horowitz [email] => eh@10gen.com ) [1] => PersonObject Object( [name] => Dwight Merriman [email] => dm@10gen.com ) ) [model] => ModelObject Object( [relational] => [awesome] => 1 ) ) array( "title" => 'MongoDB', "contributors" => array( array( 'name' => 'Eliot Horowitz', 'email' => 'eh@10gen.com' ), array( 'name' => 'Dwight Merriman', 'email' => 'dm@10gen.com' ) ), "model" => array( 'relational' => false, 'awesome' => true Tables to Documents { title: ‘MongoDB’, contributors: [ { name: ‘Eliot Horowitz’, email: ‘eh@10gen.com’ }, { name: ‘Dwight Merriman’, email: ‘dm@10gen.com’ } ], model: { relational: false, awesome: true } } Documents to Arrays Documents to Objects 7 Saturday 18 August 2012
  10. 10. First things first 8 Saturday 18 August 2012
  11. 11. PHP Driver No dependencies https://github.com/mongodb/mongo-php-driver/downloads Maintained and supported by 10gen $ pecl install mongo extension = mongo.so 9 Saturday 18 August 2012
  12. 12. Connecting to the DB If the DB or collection doesn’t exist, mongoDB will create it on connect. $connection = new Mongo(); $db = $connection->selectDB('blog'); $posts = $db->post; 10 mongo.default_host = localhost mongo.default_port = 27017 Saturday 18 August 2012
  13. 13. Connecting to ReplicaSet If one of the servers is down, we’ll connect to the next one Auto-discovery of the RS topology $connection = new Mongo('server1,server2', array(‘replicaSet’ => ‘myReplicaSet’)); $db = $connection->selectDB('blog'); $posts = $db->post; 11 Saturday 18 August 2012
  14. 14. Documents Blog Post Document $p1 = array("author" => "roger", "date" => new MongoDate(), "text" => "about mongoDB...", "tags" => array('tech', 'databases'), ); $posts->insert($p1); 12 Saturday 18 August 2012
  15. 15. Silly Billy No error check! try { $posts->insert($p1, array("safe" => true)); catch( Exception $e ) { echo $e->getMessage(); /* ... */ } 13 Saturday 18 August 2012
  16. 16. Querying Note: _id is unique, but can be anything you’d like > db.posts.findOne() > { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), author : "roger", date : "Sat Jul 24 2010 19:47:11", text : "About MongoDB...", tags : [ "tech", "databases" ] } print_r($posts->findOne()); print_r($p1); Array( [_id] => MongoId Object( [$id] => 4e9796764a18173a17000000 ) [author] => roger [date] => MongoDate Object( [sec] => 1318557302 [usec] => 581000 ) [text] => about mongoDB... [tags] => Array( [0] => tech [1] => databases ) ) 14 Saturday 18 August 2012
  17. 17. Querying Note: _id is unique, but can be anything you’d like > db.posts.findOne() > { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), author : "roger", date : "Sat Jul 24 2010 19:47:11", text : "About MongoDB...", tags : [ "tech", "databases" ] } print_r($posts->findOne()); print_r($p1); Array( [_id] => MongoId Object( [$id] => 4e9796764a18173a17000000 ) [author] => roger [date] => MongoDate Object( [sec] => 1318557302 [usec] => 581000 ) [text] => about mongoDB... [tags] => Array( [0] => tech [1] => databases ) ) 14 Saturday 18 August 2012
  18. 18. MongoId An autogenerated primary key $x = array("foo" => 1, "bar" => 2); $db->baz->insert($x); var_dump($x['_id']); Result: object(MongoId)#4 (1) { ["$id"]=> string(24) "4e9cc76a4a1817fd21000000" } 15 Saturday 18 August 2012
  19. 19. MongoId An autogenerated primary key object(MongoId)#4 (1) { ["$id"]=> string(24) "4e9cc76a4a1817fd21000000" } 12bytes 4e9cc76a4a1817fd21000000 |------||----||--||----| ts machine pid inc 16 Saturday 18 August 2012
  20. 20. Update Operations $set, $unset, $inc, $push, $pushAll, $pull, $pullAll, $bit $change = array('$push' => array('comments' => array( 'author' => 'Fred', 'created' => new MongoDate(), 'comment' => 'Best post ever!.' ) ) ); $posts->update(array("_id" => $id), $change); 17 Saturday 18 August 2012
  21. 21. Array( [_id] => MongoId Object ( [$id] => 4e9796764a18173a17000000 ) [author] => roger [comments] => Array( [0] => Array( [author] => Fred [created] => MongoDate Object( [sec] => 1318899392 [usec] => 176000 ) [comment] => Dumb post. ) ) [date] => MongoDate Object( [sec] => 1318557302 [usec] => 581000 ) [tags] => Array( [0] => tech [1] => databases ) [text] => about mongoDB... ) Nested Documents { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), author : "roger", date : ISODate("2012-08-13T11:11:00.294Z"), text : "About MongoDB...", tags : [ "tech", "databases" ], comments : [ { author : "Fred", created : ISODate("2012-08-13T11:41:00.634Z"), comment : "Best Post Ever!" } ] } 18 Saturday 18 August 2012
  22. 22. Array( [_id] => MongoId Object ( [$id] => 4e9796764a18173a17000000 ) [author] => roger [comments] => Array( [0] => Array( [author] => Fred [created] => MongoDate Object( [sec] => 1318899392 [usec] => 176000 ) [comment] => Dumb post. ) ) [date] => MongoDate Object( [sec] => 1318557302 [usec] => 581000 ) [tags] => Array( [0] => tech [1] => databases ) [text] => about mongoDB... ) Nested Documents { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), author : "roger", date : ISODate("2012-08-13T11:11:00.294Z"), text : "About MongoDB...", tags : [ "tech", "databases" ], comments : [ { author : "Fred", created : ISODate("2012-08-13T11:41:00.634Z"), comment : "Best Post Ever!" } ] } 18 Saturday 18 August 2012
  23. 23. Querying $posts = $blog->find(array( "author" => "Roger")); $commentsByFred = $blog->find(array( "comments.author" => "Fred")); $commentsByFred = $blog->find(array( "comments.author" => new MongoRegex("/fred/i"))); 19 Saturday 18 August 2012
  24. 24. It’s all about the $ $ instead of >, <, =, etc. $gt, $gte, $lt, $lte, $eq, $neq, $exists, $set, $mod, $where, $in, $nin, $inc $push, $pull, $pop, $pushAll, $popAll $c->find(array("x" => array('$gt' => 4))); $c->find(array("x" => array(“$gt” => 4))); 20 Saturday 18 August 2012
  25. 25. It’s all about the $ $ instead of >, <, =, etc. $gt, $gte, $lt, $lte, $eq, $neq, $exists, $set, $mod, $where, $in, $nin, $inc $push, $pull, $pop, $pushAll, $popAll $c->find(array("x" => array('$gt' => 4))); $c->find(array("x" => array(“$gt” => 4))); 20 Saturday 18 August 2012
  26. 26. Adjust the behavior in php.ini or using ini_set() php.ini --------------- mongo.cmd = ":" $c->find(array("x" => array(':gt' => 4))); or ini_set("mongo.cmd", "."); $c->find(array("x" => array('.gt' => 4))); 21 Saturday 18 August 2012
  27. 27. Indexing $people->ensureIndex(array("age" => 1)); $people->ensureIndex(array( "name" => -1, "ts" => -1, "comments.author" => 1 )); 22 Saturday 18 August 2012
  28. 28. More Indexing // Index nested documents $posts->ensureIndex( array("comments.author" => 1) ) $posts->find( array("comments.author" => "Fred") ) // Index on tags (multi-key index) $posts->ensureIndex( array("tags" => 1 ) ) $posts->find( array("tags" => "tech") ) // geospatial index $posts->ensureIndex( array("author.location" => "2d") ) $posts->find( array("author.location" => array( '$near' => array(22,42))); 23 Saturday 18 August 2012
  29. 29. Cursors $cursor = $c->find(array("foo" => "bar")) foreach ($cursor as $id => $value) { echo "$id: "; var_dump( $value ); } $a = iterator_to_array($cursor); 24 Saturday 18 August 2012
  30. 30. Paging $page_num = 3; $results_per_page = 10; $cursor = $results->find() ->sort(array("ts" => -1)) ->skip($page_num * $results_per_page) ->limit($results_per_page); 25 Saturday 18 August 2012
  31. 31. Rich Documents { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), line_items : [ { sku: ‘tt-123’, name: ‘Coltrane: Impressions’ }, { sku: ‘tt-457’, name: ‘Davis: Kind of Blue’ } ], address : { name: ‘Banker’, street: ‘111 Main’, zip: 10010 }, payment: { cc: 4567, exp: Date(2011, 7, 7) }, subtotal: 2355 } 26 Saturday 18 August 2012
  32. 32. Libraries & Frameworks • Doctrine MongoDB ODM • Zend Framework • Lithium • Symfony2 • Kohana • Drupal • Yii 27 Saturday 18 August 2012
  33. 33. Doctrine MongoDB ODM • Provides full validation • Seamless integration with Doctrine ORM – Useful for hybrid solutions • Follows same persistence model as Doctrine • Uses a Document Manager & annotations • Supports embedded and referenced objects • Can use mongo’s query interface • Supports in place updates https://github.com/doctrine/mongodb-odm 28 Saturday 18 August 2012
  34. 34. Grid FS Saturday 18 August 2012
  35. 35. Storing Files Under 16mb Saturday 18 August 2012
  36. 36. Storing Big Files >16mb stored in 16mb chunks Saturday 18 August 2012
  37. 37. Storing Big Files Works with replicated and sharded systems Saturday 18 August 2012
  38. 38. A better network FS • GridFS files are seamlessly sharded & replicated. • No OS constraints... • No file size limits • No naming constraints • No folder limits • Standard across different OSs • MongoDB automatically generate the MD5 hash of the file Saturday 18 August 2012
  39. 39. Storing Files $grid = $db->getGridFS(); // The file's location in the File System $path = "/tmp/"; $filename = "movie.mp4"; // Note metadata field & filename field $storedfile = $grid->storeFile($path . $filename, array ("metadata" => array("filename" => $filename), "filename" => $filename)); // Return newly stored file's Document ID echo $storedfile; Saturday 18 August 2012
  40. 40. Storing Data $grid = $db->getGridFS(); $filename = "zelda.jpg"; $storedfile = $grid->storeBytes("√ø√ò√ø√⠀ ^@^PJFIF^@^A^A^A,^G^E^E^G,...", array("metadata" => array("filename" => $filename), "filename" => $filename)); Saturday 18 August 2012
  41. 41. Streaming Data $gridFS = $db->getGridFS(); // Find image to stream $image = $gridFS->findOne("zelda.jpg"); // Stream image to browser header('Content-type: image/jpeg'); echo $image->getBytes(); Saturday 18 August 2012
  42. 42. PS: We’re hiring!! Contact us at jobs@10gen.com Questions? download at mongodb.org 37 Saturday 18 August 2012
  1. A particular slide catching your eye?

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

×