Doctrine and NoSQL
-
Upload
benjamin-eberlei -
Category
Technology
-
view
6.908 -
download
2
description
Transcript of Doctrine and NoSQL
![Page 1: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/1.jpg)
Doctrine NoSQL
Benjamin Eberlei (SimpleThings GmbH)
![Page 2: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/2.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/3.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/4.jpg)
Doctrine Subprojects
DBAL and ORMDocument Mapper (MongoDB, CouchDB, PHPCR)AnnotationsXMLWhat is next?
![Page 5: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/5.jpg)
Doctrine Philosophy
Separate Persistence and Model
![Page 6: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/6.jpg)
Doctrine Philosophy
Similar look and feel
![Page 7: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/7.jpg)
Doctrine Philosophy
Embrace Differences
![Page 8: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/8.jpg)
Why NoSQL Mapper?
Schemaless storage allows:
Arbitrary associationsEmbedded objectsLists and Associative Arrays
No duplicate schema-maintenance!
![Page 9: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/9.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/10.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/11.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/12.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/13.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/14.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/15.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/16.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/17.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/18.jpg)
Persistence API Use-Cases
Focus on "in memory" object workflowsSpecialized reusable ModulesSymfony2:
User ManagementCommentAdmin Generatorslichess.org
![Page 19: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/19.jpg)
Associations in NoSQL
Pros
Embedded DocumentsReferences between arbitrary types
Cons
No referential integrityNo support for transactions
![Page 20: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/20.jpg)
Association Mappings<?php/** @Document */class Blog{ /** @ReferenceMany */ private $articles; /** @ReferenceOne(targetDocument="User") */ private $owner;}
![Page 21: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/21.jpg)
Association keys<?php$id = "1";$articleSlug = "hello-world";
$blog = $dm->find("Blog", $id);$blog->articles[$articleSlug]->getHeadline();
![Page 22: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/22.jpg)
Embedded Mappings<?php/** @Document */class User{ /** @EmbedMany */ private $phonenumbers; /** @EmbedOne(targetDocument="Address") */ private $address;}
![Page 23: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/23.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/24.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/25.jpg)
Document Version
Implement Optimistic-Locking
<?phpclass Article{ /** @Version */ private $version;}
$article = $dm->find( "Article", $id, $expectedVersion);
![Page 26: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/26.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/27.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/28.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/29.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/30.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/31.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/32.jpg)
MongoDB and Doctrine
Indexing and on the flyqueriesVery fastIn-Place Updates²GridFS, GeolocationShardingDoctrine MongoDB 1.0 Beta2
![Page 33: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/33.jpg)
Complex Associations<?phpclass User{ /** * @ReferenceMany( * targetDocument="Comment", * mappedBy="blogPost", * sort={"date"="desc"}, * limit=5) */ private $last5Comments;}
![Page 34: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/34.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/35.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/36.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/37.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/38.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/39.jpg)
More of Doctrine MongoDB
Support for TreesSupport for Files in MongoGridFSCapped CollectionsTailable Cursors
![Page 40: Doctrine and NoSQL](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/40.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/41.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/42.jpg)
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](https://reader031.fdocuments.in/reader031/viewer/2022013121/5455b0a2af79592b448b4a6b/html5/thumbnails/43.jpg)
Thank you!
Rate this talk:
http://joind.in/talk/view/3515