Symfony2 and MongoDB

62
Pablo Godel @pgodel - 2012.phpDay.it May 18th 2012 - Verona, Italy https://joind.in/6383 Friday, May 18, 2012

description

See how to use MongoDB in Symfony2 projects to speed up the development of web applications. We will give an introduction of MongoDB as a NoSQL database server and look at the options on how to work with it from Symfony2 and PHP applications.

Transcript of Symfony2 and MongoDB

Page 1: Symfony2 and MongoDB

Pablo Godel @pgodel - 2012.phpDay.it May 18th 2012 - Verona, Italy

https://joind.in/6383

Friday, May 18, 2012

Page 2: Symfony2 and MongoDB

Who Am I?

⁃ Born in Argentina, living in the US since 1999⁃ PHP & Symfony developer

⁃ Founder of the original PHP mailing list in spanish ⁃ Master of the parrilla

Friday, May 18, 2012

Page 3: Symfony2 and MongoDB

Who Am I?

⁃ Born in Argentina, living in the US since 1999⁃ PHP & Symfony developer

⁃ Founder of the original PHP mailing list in spanish ⁃ Master of the parrilla

Friday, May 18, 2012

Page 4: Symfony2 and MongoDB

Friday, May 18, 2012

Page 5: Symfony2 and MongoDB

⁃ Founded ServerGrove Networks in 2005

⁃ Provider of web hosting specialized in PHP, Symfony, ZendFramework, and others

⁃ Mongohosting.com under beta!

ServerGrove!

Friday, May 18, 2012

Page 6: Symfony2 and MongoDB

⁃ Very active open source supporter through codecontributions and usergroups/conference sponsoring

Community is our teacher

Friday, May 18, 2012

Page 7: Symfony2 and MongoDB

Agenda

- Introduction to MongoDB- PHP and MongoDB- PHP Libraries- Symfony2 and MongoDB

Friday, May 18, 2012

Page 8: Symfony2 and MongoDB

What is MongoDB?

Who is 10Gen?

Friday, May 18, 2012

Page 9: Symfony2 and MongoDB

MongoMongo as in "humongous". Used to describe something extremely large or important.

Friday, May 18, 2012

Page 10: Symfony2 and MongoDB

MongoDB is a scalable, high-performance, open source NoSQL database.

- Document Oriented DB- Written in C++

- Available for *nux (Linux, Solaris, etc), Windows and OS X

- Lots of Drivers (PHP, Java, Python, Ruby...)

Friday, May 18, 2012

Page 11: Symfony2 and MongoDB

- Flexible JSON-style documents- Full Indexing- Complex Queries / Map Reduce- Aggregation Framework (coming soon)- GridFS (store files natively)- Multiple Replication Options- Sharding- Simple Installation / Zero Config

Features

Friday, May 18, 2012

Page 12: Symfony2 and MongoDB

Document Oriented

Database => DatabaseTable => CollectionRow => Document

Coming from SQL?

Friday, May 18, 2012

Page 13: Symfony2 and MongoDB

JSON-style documents

{ name: { first: 'John', last: 'Doe' }, title: 'Engineer', age: 40}

Friday, May 18, 2012

Page 14: Symfony2 and MongoDB

No Schema or fixed tables

{ name: { first: 'Foo', last: 'Bar' }, title: 'Student', school: 'Harvard'}

Friday, May 18, 2012

Page 15: Symfony2 and MongoDB

Embedded documents{ "_id" : ObjectId("4ccba15ef597e9352e060000") "srcFilename" : "/etc/apache2/sites-enabled/example1.com", "vhostDirective" : { "directives" : [ { "name" : "CustomLog", "value" : "logs/example1.com-access_log combined" }, { "name" : "DocumentRoot", "value" : "/var/www/vhosts/example1.com/httpdocs" }, { "name" : "ServerName", "value" : "example1.com" } ] } }

Friday, May 18, 2012

Page 16: Symfony2 and MongoDB

Document Referencing{ "_id" : ObjectId("4cc4a5c3f597e9db6e010109"), "billingId" : NumberLong(650), "created" : ISODate("2010-10-24T21:31:47Z"), "servers" : [ { "$ref" : "server", "$id" : ObjectId("4cc4a5c4f597e9db6e050201") }], "users" : [ { "$ref" : "user", "$id" : ObjectId("4cc4a5c4f597e9db6e980201") }, { "$ref" : "user", "$id" : ObjectId("4cc4a5c4f597e9db6e9c0201") }] }

Friday, May 18, 2012

Page 17: Symfony2 and MongoDB

Full Indexing

db.coll.ensureIndex({name.last: 1})

db.coll.ensureIndex({name.first: 1, name.last: 1})

db.coll.ensureIndex({age: 0})

Friday, May 18, 2012

Page 18: Symfony2 and MongoDB

Querying

db.coll.find({name: 'John'})

db.coll.find({keywords: 'storage'})

db.coll.find({keywords: {$in: ['storage', 'DBMS']}}

Friday, May 18, 2012

Page 19: Symfony2 and MongoDB

GridFS

- Files are divided in chunks and stored over multiple documents

- Transparent API

Friday, May 18, 2012

Page 22: Symfony2 and MongoDB

Simple Installation/Zero Config

wget http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-2.0.4.tgz

tar zxvf mongodb-osx-x86_64-2.0.4.tgz

cd mongodb-osx-x86_64-2.0.4

./mongod

OS X

Friday, May 18, 2012

Page 23: Symfony2 and MongoDB

/etc/yum.repos.d/10gen.repo

CentOS Linux

[10gen]name=10gen Repositorybaseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64gpgcheck=0

$ yum install -y mongo-stable-server$ service mongod start

Simple Installation/Zero Config

Friday, May 18, 2012

Page 24: Symfony2 and MongoDB

Why is MongoDB good for Rapid Development of Web Apps?

Friday, May 18, 2012

Page 25: Symfony2 and MongoDB

Schema-less / Document Oriented

FLEXIBILITY

Rapid Development

by exfordy

Friday, May 18, 2012

Page 26: Symfony2 and MongoDB

EASIER MIGRATIONS

by exfordy

Rapid Development

Schema-less / Document Oriented

Friday, May 18, 2012

Page 27: Symfony2 and MongoDB

NO JOINS!

Rapid Development

Friday, May 18, 2012

Page 28: Symfony2 and MongoDB

SPEED

by xavi talleda

Performance

Friday, May 18, 2012

Page 29: Symfony2 and MongoDB

SCALABILITY

by Jimee, Jackie, Tom & Asha

Performance

Friday, May 18, 2012

Page 30: Symfony2 and MongoDB

No TransactionsNo Rollbacks

Unsafe defaultsMap Reduce locks

A Word of Caution

by Ernst Vikne

Friday, May 18, 2012

Page 31: Symfony2 and MongoDB

Great Use Cases

- Content Management

- Product Catalogs

- Realtime Analytics

- Logs Storage

Friday, May 18, 2012

Page 32: Symfony2 and MongoDB

and

Friday, May 18, 2012

Page 33: Symfony2 and MongoDB

PECL driver

pecl install mongoecho “extension=mongo.so >> /path/php.ini”

Linux

OS X

Windowshttps://github.com/mongodb/mongo-php-driver/downloads

http://php-osx.liip.ch/

Friday, May 18, 2012

Page 34: Symfony2 and MongoDB

<?php

// connect$m = new Mongo();

// select a database$db = $m->comedy;

// select a collection (analogous to a relational database's table)$collection = $db->cartoons;

// add a record$obj = array( "title" => "Calvin and Hobbes", "author" => "Bill Watterson" );$collection->insert($obj);

// add another record, with a different "shape"$obj = array( "title" => "XKCD", "online" => true );$collection->insert($obj);

// find everything in the collection$cursor = $collection->find();

// iterate through the resultsforeach ($cursor as $obj) {    echo $obj["title"] . "\n";}

?>

Usage

Friday, May 18, 2012

Page 35: Symfony2 and MongoDB

<?php

// save a file$id = $grid->storeFile("game.tgz");$game = $grid->findOne();

// add a downloads counter$game->file['downloads'] = 0;$grid->save($game->file);

// increment the counter$grid->update(array("_id" => $id), array('$inc' => array("downloads" => 1)));

?>

Storing Files

Friday, May 18, 2012

Page 36: Symfony2 and MongoDB

SQL to Mongo Mapping Chart

This is a PHP-specific version of the » SQL to Mongo mapping chart in the main docs.

SQL StatementMongo Query Language Statement

CREATE TABLE USERS (a Number, b Number)Implicit or use MongoDB::createCollection().INSERT INTO USERS VALUES(1,1)$db->users->insert(array("a" => 1, "b" => 1));SELECT a,b FROM users$db->users->find(array(), array("a" => 1, "b" => 1));SELECT * FROM users WHERE age=33$db->users->find(array("age" => 33));SELECT a,b FROM users WHERE age=33$db->users->find(array("age" => 33), array("a" => 1, "b" => 1));SELECT a,b FROM users WHERE age=33 ORDER BY name$db->users->find(array("age" => 33), array("a" => 1, "b" => 1))->sort(array("name" => 1));SELECT * FROM users WHERE age>33$db->users->find(array("age" => array('$gt' => 33)));SELECT * FROM users WHERE age<33$db->users->find(array("age" => array('$lt' => 33)));SELECT * FROM users WHERE name LIKE "%Joe%"$db->users->find(array("name" => new MongoRegex("/Joe/")));SELECT * FROM users WHERE name LIKE "Joe%"$db->users->find(array("name" => new MongoRegex("/^Joe/")));SELECT * FROM users WHERE age>33 AND age<=40$db->users->find(array("age" => array('$gt' => 33, '$lte' => 40)));SELECT * FROM users ORDER BY name DESC

http://php.net/manual/en/mongo.sqltomongo.php

SQL to Mongo Queries

Friday, May 18, 2012

Page 37: Symfony2 and MongoDB

Admin Interfaces

- Genghis

- RockMongo

- php-mongodb-admin

http://genghisapp.com/

http://code.google.com/p/rock-php/wiki/rock_mongo

https://github.com/jwage/php-mongodb-admin

Friday, May 18, 2012

Page 38: Symfony2 and MongoDB

- Doctrine ODM

- Mandango

- many more...

PHP Libraries

Friday, May 18, 2012

Page 39: Symfony2 and MongoDB

Doctrine MongoDB ODM

http://doctrine-project.org

Doctrine MongoDB Object Document Mapper is built for PHP 5.3.2+ and provides transparent

persistence for PHP objects.

Friday, May 18, 2012

Page 40: Symfony2 and MongoDB

/** @Document */class User{ /** @Id */ private $id;

/** @String */ private $name;

/** @String */ private $email;

/** @ReferenceMany(targetDocument="BlogPost", cascade="all") */ private $posts = array();

// ...}

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 41: Symfony2 and MongoDB

/** @Document */class BlogPost{ /** @Id */ private $id;

/** @String */ private $title;

/** @String */ private $body;

/** @Date */ private $createdAt;

// ...}

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 42: Symfony2 and MongoDB

<?php

// create user$user = new User();$user->setName('Bulat S.');$user->setEmail('[email protected]');

// tell Doctrine 2 to save $user on the next flush()$dm->persist($user);

// create blog post$post = new BlogPost();$post->setTitle('My First Blog Post');$post->setBody('MongoDB + Doctrine 2 ODM = awesomeness!');$post->setCreatedAt(new DateTime());

$user->addPost($post);

// store everything to MongoDB$dm->flush();

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 43: Symfony2 and MongoDB

Array( [_id] => 4bec5869fdc212081d000000 [title] => My First Blog Post [body] => MongoDB + Doctrine 2 ODM = awesomeness! [createdAt] => MongoDate Object ( [sec] => 1273723200 [usec] => 0 ))

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 44: Symfony2 and MongoDB

Array( [_id] => 4bec5869fdc212081d010000 [name] => Bulat S. [email] => [email protected] [posts] => Array ( [0] => Array ( [$ref] => blog_posts [$id] => 4bec5869fdc212081d000000 [$db] => test_database ) ))

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 45: Symfony2 and MongoDB

$user = $dm->find('User', $userId);

$user = $dm->getRepository('User')->findOneByName('Bulat S.');

$posts = $user->getPosts();foreach ($posts as $post) { echo $post;}

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 46: Symfony2 and MongoDB

// src/YourNamespace/YourBundle/ServerRepository.phpnamespace YourNamespace\YourBundle;

use Doctrine\ODM\MongoDB\DocumentRepository;

class ServerRepository extends DocumentRepository{ public function getActiveServers() { return $this->createQueryBuilder() ->field('isActive')->equals(true) ->sort('name', 'asc')->getQuery()->execute(); }

Document Repositories

$rep = $dm->getRepository(‘@YourBundle/Server’);$servers = $rep->getActiveServers();

Usage

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 47: Symfony2 and MongoDB

/** @Document */class Image{ /** @Id */ private $id;

/** @Field */ private $name;

/** @File */ private $file;

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 48: Symfony2 and MongoDB

// store file$image = new Image();$image->setName('Test image');$image->setFile('/path/to/image.png');

$dm->persist($image);$dm->flush();

// retrieve and return file to client$image = $dm->createQueryBuilder('Documents\Image') ->field('name')->equals('Test image') ->getQuery() ->getSingleResult();

header('Content-type: image/png;');echo $image->getFile()->getBytes();

Doctrine MongoDB ODM

Friday, May 18, 2012

Page 49: Symfony2 and MongoDB

Symfony is a PHP Web Development Framework.

Friday, May 18, 2012

Page 50: Symfony2 and MongoDB

Symfony2 Bundles

- DoctrineMongoDBBundle

- MandangoBundle

Friday, May 18, 2012

Page 51: Symfony2 and MongoDB

DoctrineMongoDBBundle

Installation with Composer

{ require: { "doctrine/mongodb-odm-bundle": "dev-master" }}

$ php composer.phar update

composer.json

Friday, May 18, 2012

Page 52: Symfony2 and MongoDB

Configuring Symfony2

use Doctrine\Common\Annotations\AnnotationRegistry;

AnnotationRegistry::registerFile(__DIR__.'/../vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DoctrineAnnotations.php');

app/autoload.php

DoctrineMongoDBBundle

Friday, May 18, 2012

Page 53: Symfony2 and MongoDB

Configuring Symfony2

doctrine_mongodb: connections: default: server: mongodb://localhost:27017 options: connect: true default_database: test_database document_managers: default: auto_mapping: true

app/config/config.yml

DoctrineMongoDBBundle

Friday, May 18, 2012

Page 54: Symfony2 and MongoDB

app/config/config.ymldoctrine_mongodb: connections: default: server: mongodb://localhost:27017 options: connect: true

usage: server: mongodb://user:[email protected]:27017 options: replicaSet: true connect: true default_database: test_database document_managers: default: mappings: SGCBundle: ~ SGCRepositoryAppBundle: yml MyBundle: { type: xml, dir: Resources/config/doctrine/mapping }

DoctrineMongoDBBundle

Friday, May 18, 2012

Page 55: Symfony2 and MongoDB

Defining Documents

DoctrineMongoDBBundle

Friday, May 18, 2012

Page 56: Symfony2 and MongoDB

Defining Documents// src/Acme/StoreBundle/Document/Product.phpnamespace Acme\StoreBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/** * @MongoDB\Document(collection="product") */class Product{ /** * @MongoDB\Id */ protected $id;

/** * @MongoDB\String @MongoDB\Index(unique=true, order="asc") */ protected $name;

DoctrineMongoDBBundle

Friday, May 18, 2012

Page 57: Symfony2 and MongoDB

Using Documents// src/Acme/StoreBundle/Controller/DefaultController.phpuse Acme\StoreBundle\Document\Product;use Symfony\Component\HttpFoundation\Response;// ...

public function createAction(){ $product = new Product(); $product->setName('A Foo Bar'); $product->setPrice('19.99');

$dm = $this->get('doctrine.odm.mongodb.document_manager'); $dm->persist($product); $dm->flush();

return new Response('Created product id '.$product->getId());}

DoctrineMongoDBBundle

Friday, May 18, 2012

Page 58: Symfony2 and MongoDB

FormsSince Documents are Plain PHP Objects integrating it with Symfony Forms is straightforward.

public function createAction(){ $dm = $this->get('doctrine.odm.mongodb.default_document_manager');

$form = $this->createForm(new RegistrationType(), new Registration());

$form->bindRequest($this->getRequest());

if ($form->isValid()) { $registration = $form->getData();

$dm->persist($registration->getUser()); $dm->flush();

return $this->redirect(...); }

http://symfony.com/doc/master/bundles/DoctrineMongoDBBundle/form.html

Friday, May 18, 2012

Page 59: Symfony2 and MongoDB

Symfony2 Commandsdoctrine doctrine:mongodb:cache:clear-metadata Clear all metadata cache for a document manager. doctrine:mongodb:fixtures:load Load data fixtures to your database. doctrine:mongodb:generate:documents Generate document classes and method stubs from your mapping information. doctrine:mongodb:generate:hydrators Generates hydrator classes for document classes. doctrine:mongodb:generate:proxies Generates proxy classes for document classes. doctrine:mongodb:generate:repositories Generate repository classes from your mapping information. doctrine:mongodb:mapping:info Show basic information about all mapped documents. doctrine:mongodb:query Query mongodb and inspect the outputted results from your document classes. doctrine:mongodb:schema:create Allows you to create databases, collections and indexes for your documents doctrine:mongodb:schema:drop Allows you to drop databases, collections and indexes for your documents

Commands

Friday, May 18, 2012

Page 60: Symfony2 and MongoDB

Bundles using MongoDB

- SonataDoctrineMongoDBAdminBundle

- IsmaAmbrosiGeneratorBundle

- EbutikMongoSessionBundle

- TranslationEditorBundle

- ServerGroveLiveChat

Friday, May 18, 2012

Page 61: Symfony2 and MongoDB

Questions?

Friday, May 18, 2012

Page 62: Symfony2 and MongoDB

Thank you!

Rate Me Please! https://joind.in/6383Slides: http://slideshare.net/pgodel

Twitter: @pgodelE-mail: [email protected]

Friday, May 18, 2012