symflo / mongodb-odm
MongoDB object document mapper
Requires
- php: >=5.4.0
- symfony/serializer: 2.4.*@dev
This package is not auto-updated.
Last update: 2024-12-17 04:20:33 UTC
README
Simple Object Document Mapper for PHP and MongoDB.
Requirements
- PHP 5.4+
- MongoDB driver
Basic Usage
<?php require 'vendor/autoload.php'; use \Symflo\MongoDBODM\DocumentManagerFactory; $config = array( 'user' => 'user', 'password' => 'password', 'database' => 'db', 'host' => '127.0.0.1', 'documents' => array( 'user' => array( 'class' => 'Symflo\MongoDBODM\Document\UserDocument', 'collectionName' => 'users', 'collectionClass' => 'Symflo\MongoDBODM\Document\UserCollection' ), 'preference' => array( 'class' => 'Symflo\MongoDBODM\Document\PreferenceDocument' ), 'message' => array( 'class' => 'Symflo\MongoDBODM\Document\MessageDocument', 'collectionName' => 'messages' ), 'role' => array( 'class' => 'Symflo\MongoDBODM\Document\RoleDocument' ) ), 'types' => array( //'custom' => new \CustomPath\Type\myDateType(), ) ); //Prefer DIC as this factory list($indexer, $dm) = DocumentManagerFactory::create($config); //Multiple insert $message = new \Symflo\MongoDBODM\Document\MessageDocument(); $message->setId((string) new \MongoId()); $message->setText('Text1'); $message2 = new \Symflo\MongoDBODM\Document\MessageDocument(); $message2->setId((string) new \MongoId()); $message2->setText('Text2'); $dm->batchInsert(array($message, $message2)); ?>
Simple Insert, update and delete.
<?php $user = new \Symflo\MongoDBODM\Document\UserDocument(); $user->setUsername('CN'); $user->setFirstname('Chuck'); $user->setMessage($message); //manual reference $user->setMessages(array($message, $message2)); //manual references $user->setCreatedAt((new DateTime())->format('Y-m-d H:i:s')); //insert $dm->save($user); //update $user->setFirstname('Chucky') $dm->save($user); //delete $dm->remove($user); ?>
To find objects, use native query from \MongoCollection
.
<?php $coll = $dm->getCollection('users'); $users = $coll->find(); //return DocumentCollection $user = $coll->findOne(array('username' => 'CN')); //return Document $user->getUsername(); //return 'CN' $user->getMongoId(); //return \MongoId $coll->drop(); ?>
Create query with your object collection.
Without joins:
<?php $coll = $dm->getCollection('users'); $user = $coll->findOneByUsername('CN'); $user->getMessages(); //return null $user->getMessageIds(); //return \MongoId array $user->getMessage(); //return null $user->getMessageId(); //return \MongoId ?>
With joins:
<?php $coll->addJoin('messageId') ->addJoin('messageIds') ->findOneByUsername('TES3'); $user->getMessages(); //return DocumentCollection MessageDocument $user->getMessageIds(); //return \MongoId array $user->getMessage(); //return MessageDocument $user->getMessageId(); //return \MongoId ?>
Manage simple embedded.
<?php $preference = new \Symflo\MongoDBODM\Document\PreferenceDocument(); $preference->setAlert(true); $user = new \Symflo\MongoDBODM\Document\UserDocument(); $user->setUsername('TES3'); $user->setFirstname('Norris'); $user->setMessage($message); $user->setMessages(array($message, $message2)); $user->setCreatedAt(new \MongoDate()); $user->setRoles(new DocumentCollection(array($roleAdmin, $roleAdmin, $roleSuperAdmin))); //Collection in user $user->setPreference($preference); //or $user->setPreference(array('alert' => true)); $dm->save($user); //then $coll = $dm->getCollection('users'); $coll->addJoin('preference') // get object instead of array ->findOneByUsername('TES3'); ?>
Manage embedded collection.
<?php $roleAdmin = new \Symflo\MongoDBODM\Document\RoleDocument(); $roleAdmin->setRole('ROLE_ADMIN'); $roleAdmin->setAddedAt((new DateTime())->format('Y-m-d H:i:s')); $roleSuperAdmin = new \Symflo\MongoDBODM\Document\RoleDocument(); $roleSuperAdmin->setRole('ROLE_SUPER_ADMIN'); $roleSuperAdmin->setAddedAt((new DateTime())->format('Y-m-d H:i:s')); $user = new \Symflo\MongoDBODM\Document\UserDocument(); //$user->setId('your_custom_id'); $user->setUsername('TES3'); $user->setFirstname('Norris'); $user->setMessage($message); $user->setMessages(array($message, $message2)); $user->setCreatedAt(new \MongoDate()); $user->setRoles(new DocumentCollection(array($roleAdmin, $roleAdmin, $roleSuperAdmin))); //Collection in user $dm->save($user); $roleRoot = new \Symflo\MongoDBODM\Document\RoleDocument(); $roleRoot->setRole('ROLE_ROOT'); $roleRoot->setAddedAt((new DateTime())->format('Y-m-d H:i:s')); //push end roles collection $dm->push($user, 'roles', $roleRoot); ?>
Installation
Use Composer to install this library.
Into your composer.json file, just include this library with adding:
"symflo/mongodb-odm": "dev-master" Then, run composer update symflo/mongodb-odm and enjoy.
Prepare your config
<?php $config = array( 'user' => 'user', 'password' => 'password', 'database' => 'db', 'host' => '127.0.0.1', 'documents' => array( 'user' => array( 'class' => 'Symflo\MongoDBODM\Document\UserDocument', 'collectionName' => 'users', 'collectionClass' => 'Symflo\MongoDBODM\Document\UserCollection' ), 'message' => array( 'class' => 'Symflo\MongoDBODM\Document\MessageDocument', 'collectionName' => 'messages' ) // ... ), 'types' => array( //'custom' => new \CustomPath\Type\myDateType(), if you want create a custom type with own validator // see Symflo\MongoDBODM\DocumentManagerFactory::create() for list ) ); ?>
Create yours documents
User
<?php namespace Your\NS\Document; use Symflo\MongoDBODM\Document\CollectionHandler; use Symflo\MongoDBODM\Document\DocumentInterface; /** * UserDocument */ class UserDocument implements DocumentInterface { use \Symflo\MongoDBODM\Behaviour\MongoIdTrait; private $username; private $firstname; private $lastname; private $isAdmin = false; //default value private $createdAt; private $messageId; private $messageIds; private $message; private $messages; private $roles; private $preference; /** * {% inheritdoc %} */ public function getProperties() { return array( 'username' => array('type' => 'string', 'required' => true), 'firstname' => array('type' => 'string', 'required' => true), 'lastname' => array('type' => 'string'), 'isAdmin' => array('type' => 'boolean'), 'createdAt' => array('type' => 'date'), 'messageId' => array('type' => 'manualReference', 'reference' => 'message', 'target' => 'message'), 'messageIds' => array('type' => 'manualReferences', 'reference' => 'message', 'target' => 'messages'), 'roles' => array('type' => 'embeddedCollection', 'reference' => 'role'), 'preference' => array('type' => 'embeddedOne', 'reference' => 'preference') //'reference' => 'preference' if you want a document else 'reference' => false to avoid to create a document class and get an array ); } public function getMessages() { return $this->messages; } public function setMessages($messages) { $this->messages = $messages; $this->setMessageIds(CollectionHandler::getCollectionIds($messages)); } public function getMessageIds() { return $this->messageIds; } public function setMessageIds($messageIds) { $this->messageIds = $messageIds; } public function getMessage() { return $this->message; } public function setMessage($message) { $this->setMessageId(CollectionHandler::getId($message)); $this->message = $message; } public function getMessageId() { return $this->messageId; } public function setMessageId($messageId) { $this->messageId = $messageId; } public function getUsername() { return $this->username; } public function setUsername($username) { $this->username = $username; } public function getFirstname() { return $this->firstname; } public function setFirstname($firstname) { $this->firstname = $firstname; } public function getLastname() { return $this->lastname; } public function setLastname($lastname) { $this->lastname = $lastname; } public function getCreatedAt() { return $this->createdAt; } public function setCreatedAt($createdAt) { $this->createdAt = $createdAt; } public function getIsAdmin() { return $this->isAdmin; } public function setIsAdmin($isAdmin) { $this->isAdmin = $isAdmin; } public function getPreference() { return $this->preference; } public function setPreference($preference) { $this->preference = $preference; } } ?>
Preference
If you indicate a reference for embeddedOne
type, you have to create a document.
<?php class PreferenceDocument implements DocumentInterface { private $alert; public function getProperties() { return array( 'alert' => array('type' => 'boolean') ); } public function getMongoId() { return false; } public function getAlert() { return $this->alert; } public function setAlert($alert) { $this->alert = $alert; } } ?>
Message
<?php class MessageDocument implements DocumentInterface { use \Symflo\MongoDBODM\Behaviour\MongoIdTrait; private $text; /** * {% inheritdoc %} */ public function getProperties() { return array( 'id' => array('type' => 'string', 'required' => true), //only if you want to define a other type else you get \MongoId 'text' => array('type' => 'string', 'required' => true) ); } public function getText() { return $this->text; } public function setText($text) { $this->text = $text; } } ?>
Role
<?php namespace Symflo\MongoDBODM\Document; class RoleDocument implements DocumentInterface { private $role; private $addedAt; public function getProperties() { return array( 'role' => array('type' => 'string', 'required' => true), 'addedAt' => array('type' => 'string', 'required' => true) ); } public function getMongoId() { return false; } public function getRole() { return $this->role; } public function setRole($role) { $this->role = $role; } public function getAddedAt() { return $this->addedAt; } public function setAddedAt($addedAt) { $this->addedAt = $addedAt; } } ?>
If you want create your document collection.
<?php namespace Symflo\MongoDBODM\Document; use Symflo\MongoDBODM\Document\Collection; /** * UserCollection */ class UserCollection extends Collection { public function findByUsername($username) { return $this->getCollectionHandler()->find(array('username' => $username)); } public function findOneByUsername($username) { return $this->getCollectionHandler()->findOne(array('username' => $username)); } } ?>
Create your own type
<?php namespace Your\NS\Type; use Symflo\MongoDBODM\Type\TypeInterface; /** * YourType */ class YourType implements TypeInterface { public function validate($value) { //your own logic } public function getError() { // return string } public function hydrate($value, $propertyOptions) { return $value; } } ?>
Then add your class in your config.
Listeners
Listeners list:
- preSave
- postSave
- preCreate
- postCreate
- preUpdate
- postUpdate
- preRemove
- postRemove
Example on UserDocument
<?php class UserDocument implements DocumentInterface { // ... public function preSave() { if ($this->getFirstname() == 'Norris') { $this->setFirstname('Norris_test'); } } // ... ?>
Errors
<?php if (!$dm->save($user)) { foreach ($dm->getValidatorErrors() as $error) { echo $error['property']; //property name echo $error['document']; //class document echo $error['message']; //message } } ?>
EnsureIndex
Add on your collection static method indexes
.
<?php class UserCollection extends Collection { // ... public static function getIndexes() { return array( array('keys' => array('createdAt' => 1), 'options' => array('expireAfterSeconds' => 60)) //... ); } // ... } ?>
Note:expireAfterSeconds.
Then apply indexes for example during a task. When you apply it, the old indexes are deleted and new ones are created.
<?php list($indexer, $dm) = DocumentManagerFactory::create($config); $indexer->applyIndex(); ?>
TODOS
- transform method
getProperties
in config - service Listeners for preSave... more complex
- Better errors management
- Tests
- Better docs