doctrine and nosql

43
Doctrine NoSQL Benjamin Eberlei (SimpleThings GmbH)

Upload: benjamin-eberlei

Post on 01-Nov-2014

6.912 views

Category:

Technology


2 download

Tags:

DESCRIPTION

International PHP Conference Spring 2011 talk on Doctrine projects NoSQL libraries for CouchDB and MongoDB.

TRANSCRIPT

Page 1: Doctrine and NoSQL

Doctrine NoSQL

Benjamin Eberlei (SimpleThings GmbH)

Page 2: Doctrine and NoSQL

About me

Benjamin EberleiWorking at SimpleThings GmbH

http://www.simplethings.deOpen Source contributor

Doctrine2, Symfony2(Zeta Components, PHPUnit, ...)

Twitter @beberleiBlog http://www.whitewashing.de

Page 3: Doctrine and NoSQL

The Doctrine Project

www.doctrine-project.org

The Doctrine Project is the home of a selectedset of PHP libraries primarily focused onproviding persistence services and relatedfunctionality.

Page 4: Doctrine and NoSQL

Doctrine Subprojects

DBAL and ORMDocument Mapper (MongoDB, CouchDB, PHPCR)AnnotationsXMLWhat is next?

Page 5: Doctrine and NoSQL

Doctrine Philosophy

Separate Persistence and Model

Page 6: Doctrine and NoSQL

Doctrine Philosophy

Similar look and feel

Page 7: Doctrine and NoSQL

Doctrine Philosophy

Embrace Differences

Page 8: Doctrine and NoSQL

Why NoSQL Mapper?

Schemaless storage allows:

Arbitrary associationsEmbedded objectsLists and Associative Arrays

No duplicate schema-maintenance!

Page 9: Doctrine and NoSQL

Doctrine NoSQL History

MongoDB Mapper early 2010 (OpenSky)CouchDB Mapper started in October 2010 (Liip)PHPCR ODM started in early 2011 (Liip)APIs heavily inspired from ORM

Page 10: Doctrine and NoSQL

SQL and NoSQL Similarities

Extracted common persistence interfacesCovering roughly 10-20% of the use-cases

Simple Finder MethodsInsert/Update/DeleteMetadata API

Support for Annotations/XML/YAML/PHP Mapping

Page 11: Doctrine and NoSQL

Persistence Interfaces<?phpinterface ObjectManager{ function find($class, $id); function getReference($class, $id); function persist($object); function remove($object); function flush();

function getClassMetadata($class); function getRepository($class);}

Page 12: Doctrine and NoSQL

Persistence Interfaces<?phpinterface ObjectRepository{ function find($id); function findAll(); function findBy(array $criteria, $orderBy = null, $limit = null, $offset = null ) function findOneBy(array $criteria);}

Page 13: Doctrine and NoSQL

Sample Document<?php/** @Document */class Message{ /** @Id */ public $id; /** @Field(type="string") */ public $text;}

$message = new Message();$message->setText("Hello World!");

Page 14: Doctrine and NoSQL

NoSQL benefits<?php/** @Document */class Product{ /** other fields */ /** @Field(type="array") */ public $attributes; /** @Field(type="array") */ public $translations;}

$product->attributes["isbn"] = "A-B-C-D";$product->translations["de"]["name"] = "Ein Produkt";

Page 15: Doctrine and NoSQL

Working with Objects 1

Creating a new document:

<?php/** @var $dm DocumentManager */$message = new Message();$message->setText("I am new!");

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

echo "ID: " . $message->getId();

Page 16: Doctrine and NoSQL

Working with Objects 2

Find and update document:

<?php/** @var $dm DocumentManager */$message = $dm->find("Message", 1);$message->setText("New Message");$dm->flush();

Page 17: Doctrine and NoSQL

Working with Objects 3

Find and remove documents:

<?php/** @var $dm DocumentManager */$repository = $dm->getRepository("User");$criteria = array("status" => "inactive");$users = $repository->findBy($criteria);

foreach ($users AS $user) { $dm->remove($user);}$dm->flush();

Page 18: Doctrine and NoSQL

Persistence API Use-Cases

Focus on "in memory" object workflowsSpecialized reusable ModulesSymfony2:

User ManagementCommentAdmin Generatorslichess.org

Page 19: Doctrine and NoSQL

Associations in NoSQL

Pros

Embedded DocumentsReferences between arbitrary types

Cons

No referential integrityNo support for transactions

Page 20: Doctrine and NoSQL

Association Mappings<?php/** @Document */class Blog{ /** @ReferenceMany */ private $articles; /** @ReferenceOne(targetDocument="User") */ private $owner;}

Page 21: Doctrine and NoSQL

Association keys<?php$id = "1";$articleSlug = "hello-world";

$blog = $dm->find("Blog", $id);$blog->articles[$articleSlug]->getHeadline();

Page 22: Doctrine and NoSQL

Embedded Mappings<?php/** @Document */class User{ /** @EmbedMany */ private $phonenumbers; /** @EmbedOne(targetDocument="Address") */ private $address;}

Page 23: Doctrine and NoSQL

CouchDB and Doctrine

JSON DatastorageHTTP/REST APIMVCC, eventually consistent (Conflicts)ReplicationAttachmentsViews and Map/Reduce in JavascriptCouchDB LuceneDoctrine CouchDB 1.0 Alpha 1

Page 24: Doctrine and NoSQL

JSON Document{ "_id": "716104ac33c797b12d50c0a6483f1661", "_rev": "1-32db404b78f130fd8f7575905859e19b", "doctrine_metadata": { "type": "MyProject.Document.Message", "associations": { "user": "055fe8a3ab06c3998d27b6d99f5a9bdd" } }, "message": "I am a message"}

Page 25: Doctrine and NoSQL

Document Version

Implement Optimistic-Locking

<?phpclass Article{ /** @Version */ private $version;}

$article = $dm->find( "Article", $id, $expectedVersion);

Page 26: Doctrine and NoSQL

Attachments

CouchDB supports Attachments to documentsDoctrine converts into Attachment objectLazy Load binary data from the serverStream support planned

<?phpclass Article{ /** @Attachments */ public $attachments = array();}

Page 27: Doctrine and NoSQL

Attachments 2<?phpuse Doctrine\CouchDB\Attachment;

$article = $dm->find("Article", 1);$data = $article->attachments["teaser.jpg"]->getContent();

$a = Attachment::createFromBase64data($data, "image/jpg");$article->attachments["author.jpg"] = $a;

$dm->flush();

Page 28: Doctrine and NoSQL

Views

Doctrine CouchDB maps filesystem to design document:

application/ couchdb/ views/ username/ map.js reduce.js

Use javascript syntax highlighting in your IDE/Editor.

Page 29: Doctrine and NoSQL

Views 2<?phpuse Doctrine\CouchDB\View\FileFolderDesignDocument;

$path = "/path/application/couchdb";$designDoc = new FileFolderDesignDocument($path);

/* @doc $couch CouchClient */$docName = "myapp";$couch->createDesignDoc($docName, $designDoc);

Page 30: Doctrine and NoSQL

Query Views<?php/* @var $dm DocumentManager */$query = $dm->createQuery("myapp", "username");$result = $query->setStartKey("b") ->setEndKey("c") ->setLimit(10) ->setSkip(10) ->includeDocs(true) ->execute();

Using include docs creates PHP instances for you.

Page 31: Doctrine and NoSQL

Lucene Queries

Support for the CouchDB Lucene extension:

<?php$query = $dm->createLuceneQuery("lucenedoc", "users");$result = $query->setQuery('"John Galt" OR "John Wayne"') ->setLimit(10) ->setSkip(10) ->includeDocs(true) ->execute();

Page 32: Doctrine and NoSQL

MongoDB and Doctrine

Indexing and on the flyqueriesVery fastIn-Place Updates²GridFS, GeolocationShardingDoctrine MongoDB 1.0 Beta2

Page 33: Doctrine and NoSQL

Complex Associations<?phpclass User{ /** * @ReferenceMany( * targetDocument="Comment", * mappedBy="blogPost", * sort={"date"="desc"}, * limit=5) */ private $last5Comments;}

Page 34: Doctrine and NoSQL

Query API<?php$qb = $dm->createQueryBuilder('User') ->field('groups') ->all(array('Group 1', 'Group 2')) ->sort("username", "asc") ->limit(10) ->skip(10) ->execute();

Page 35: Doctrine and NoSQL

Map/Reduce<?php$qb = $dm->createQueryBuilder('Documents\User') ->field('type')->equals('sale') ->map('function() { emit(this.user.$id, 1); }') ->reduce('function(k, vals) { var sum = 0; for (var i in vals) { sum += vals[i]; } return sum; }');

Page 36: Doctrine and NoSQL

Geospatial Queries<?php/** @Document @Index(keys={"coordinates"="2d"}) */class City{ /** @EmbedOne(targetDocument="Coordinates") */ public $coordinates; /** @Distance */ public $distance;}class Coordinates{ public $lat; public $long;}

Page 37: Doctrine and NoSQL

Geospatial Queries 2

Execute a Geospatial query and find locations near a point:

<?php/* @var $dm DocumentManager */$cities = $dm->createQuery('City') ->field('coordinates')->near(50, 60) ->execute();

Page 38: Doctrine and NoSQL

Eventual Migration

Handle simple and complex schema refactorings

<?php/** @Document */class Person{ public $id;

public $name; // old

/** @AlsoLoad("name") */ public $fullName;}

Page 39: Doctrine and NoSQL

More of Doctrine MongoDB

Support for TreesSupport for Files in MongoGridFSCapped CollectionsTailable Cursors

Page 40: Doctrine and NoSQL

PHPCR ODM

PHPCR: Port of the Java Content Repository APIJackalope: Access to Apache Jackrabbit in PHPDoctrine PHPCR ODM: PHP objects from PHP Content Repositories

Page 41: Doctrine and NoSQL

Object to XML Mapper

Convert objects to XML documents and back using metadata

<?php$user = new User();$user->setFirstName('John');$user->setLastName('Doe');$user->setAddress(new Address('123 Street', 'New Haven'));$user->addContact(new CustomerContact('[email protected]'));

$xml = $marshaller->marshalToString($user);$user = $marshaller->unmarshalFromString($xml);

Page 42: Doctrine and NoSQL

Using Doctrine 2.0.x ORM?

Please checkout 2.1 BETA1

Backwards compatible!You win a present if you can prove otherwise.

Page 43: Doctrine and NoSQL

Thank you!

Rate this talk:

http://joind.in/talk/view/3515