1
PHP
♥MongoDB
Saturday 18 August 2012
• Hannes / @bjori• Icelandic
» Oslo, Norway» London, England
• PHP Driver Engineer» @10gen
• PHP Contributor
About me
2
Saturday 18 August 2012
Why I started with MongoDB
• Like creating (code, not graphics)• Productivity• Don’t want to waste my time
3
Saturday 18 August 2012
The “old” way
4
Saturday 18 August 2012
The “new” way
5
Saturday 18 August 2012
Terminology
RDBMS MongoTable, View ➜ CollectionRow ➜ JSON DocumentIndex ➜ IndexJoin ➜ Embedded DocumentPartition ➜ ShardPartition Key ➜ Shard Key
6
Saturday 18 August 2012
PostObject Object( [title] => MongoDB [contributors] => Array( [0] => PersonObject Object( [name] => Eliot Horowitz [email] => [email protected] ) [1] => PersonObject Object( [name] => Dwight Merriman [email] => [email protected] ) ) [model] => ModelObject Object( [relational] => [awesome] => 1 ))
Tables to Documents
{ title: ‘MongoDB’, contributors: [ { name: ‘Eliot Horowitz’, email: ‘[email protected]’ }, { name: ‘Dwight Merriman’, email: ‘[email protected]’ } ], model: { relational: false, awesome: true }}
Documents to Arrays
Documents to Objects
7
Saturday 18 August 2012
PostObject Object( [title] => MongoDB [contributors] => Array( [0] => PersonObject Object( [name] => Eliot Horowitz [email] => [email protected] ) [1] => PersonObject Object( [name] => Dwight Merriman [email] => [email protected] ) ) [model] => ModelObject Object( [relational] => [awesome] => 1 ))
array( "title" => 'MongoDB', "contributors" => array( array( 'name' => 'Eliot Horowitz', 'email' => '[email protected]' ), array( 'name' => 'Dwight Merriman', 'email' => '[email protected]' ) ), "model" => array( 'relational' => false, 'awesome' => true
Tables to Documents
{ title: ‘MongoDB’, contributors: [ { name: ‘Eliot Horowitz’, email: ‘[email protected]’ }, { name: ‘Dwight Merriman’, email: ‘[email protected]’ } ], model: { relational: false, awesome: true }}
Documents to Arrays
Documents to Objects
7
Saturday 18 August 2012
PostObject Object( [title] => MongoDB [contributors] => Array( [0] => PersonObject Object( [name] => Eliot Horowitz [email] => [email protected] ) [1] => PersonObject Object( [name] => Dwight Merriman [email] => [email protected] ) ) [model] => ModelObject Object( [relational] => [awesome] => 1 ))
array( "title" => 'MongoDB', "contributors" => array( array( 'name' => 'Eliot Horowitz', 'email' => '[email protected]' ), array( 'name' => 'Dwight Merriman', 'email' => '[email protected]' ) ), "model" => array( 'relational' => false, 'awesome' => true
Tables to Documents
{ title: ‘MongoDB’, contributors: [ { name: ‘Eliot Horowitz’, email: ‘[email protected]’ }, { name: ‘Dwight Merriman’, email: ‘[email protected]’ } ], model: { relational: false, awesome: true }}
Documents to Arrays
Documents to Objects
7
Saturday 18 August 2012
First things first
8
Saturday 18 August 2012
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
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 = localhostmongo.default_port = 27017
Saturday 18 August 2012
Connecting to ReplicaSet
If one of the servers is down, we’ll connect to the next oneAuto-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
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
Silly Billy
No error check!
try { $posts->insert($p1, array("safe" => true));catch( Exception $e ) { echo $e->getMessage(); /* ... */}
13
Saturday 18 August 2012
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
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
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
MongoId
An autogenerated primary key
object(MongoId)#4 (1) { ["$id"]=> string(24) "4e9cc76a4a1817fd21000000"} 12bytes
4e9cc76a4a1817fd21000000|------||----||--||----| ts machine pid inc
16
Saturday 18 August 2012
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
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
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
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
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
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
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
Indexing
$people->ensureIndex(array("age" => 1));
$people->ensureIndex(array( "name" => -1, "ts" => -1, "comments.author" => 1));
22
Saturday 18 August 2012
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
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
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
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
Libraries & Frameworks
• Doctrine MongoDB ODM
• Zend Framework• Lithium• Symfony2• Kohana• Drupal• Yii
27
Saturday 18 August 2012
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
Grid FS
Saturday 18 August 2012
Storing Files
Under 16mb
Saturday 18 August 2012
Storing Big Files
>16mb stored in 16mb chunks
Saturday 18 August 2012
Storing Big Files
Works with replicated and sharded systems
Saturday 18 August 2012
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
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
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
Streaming Data
$gridFS = $db->getGridFS();
// Find image to stream$image = $gridFS->findOne("zelda.jpg");
// Stream image to browserheader('Content-type: image/jpeg');echo $image->getBytes();
Saturday 18 August 2012
PS: We’re hiring!! Contact us at [email protected]
Questions?
download at mongodb.org
37
Saturday 18 August 2012