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

Symfony2 and MongoDB

Embed Size (px)

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.

Citation preview

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