symflo/mongodb-odm

MongoDB 对象文档映射器

dev-master 2013-10-23 18:09 UTC

This package is not auto-updated.

Last update: 2024-09-24 03:17:13 UTC


README

PHP 和 MongoDB 的简单对象文档映射器。

需求

  • PHP 5.4+
  • MongoDB 驱动程序

基本用法

<?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));
?>

简单的插入、更新和删除。

<?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);
?>

要查找对象,请使用 \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();
?>

使用您的对象集合创建查询。

无连接

<?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
?>

有连接

<?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

?>

管理简单嵌入式。

<?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');

?>

管理嵌入式集合。

<?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);

?>

安装

使用 Composer 安装此库。

在您的 composer.json 文件中,只需添加此库并添加

"symflo/mongodb-odm": "dev-master",然后运行 composer update symflo/mongodb-odm 并享受。

准备您的配置

<?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
    )
);
?>

创建您的文档

用户

<?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;
    }
}
?>

偏好

如果您为 embeddedOne 类型指定了引用,您必须创建一个文档。

<?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;
    }
}
?>

消息

<?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;
    }
}
?>

角色

<?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;
    }
}
?>

如果您想创建自己的文档集合。

<?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));
    }
}
?>

创建您自己的类型

<?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;
    }
}
?>

然后将您的类添加到您的配置中。

监听器

监听器列表

  • preSave
  • postSave
  • preCreate
  • postCreate
  • preUpdate
  • postUpdate
  • preRemove
  • postRemove

UserDocument 上的示例

<?php

class UserDocument implements DocumentInterface
{
    // ...
    public function preSave()
    {
        if ($this->getFirstname() == 'Norris') {
            $this->setFirstname('Norris_test');
        }
    }

    // ...
?>

错误

<?php

if (!$dm->save($user)) {
    foreach ($dm->getValidatorErrors() as $error) {
        echo $error['property']; //property name
        echo $error['document']; //class document
        echo $error['message']; //message
    }
}

?>

确保索引

在您的集合静态方法 indexes 中添加。

<?php
class UserCollection extends Collection
{
    // ...

    public static function getIndexes()
    {
        return array(
            array('keys' => array('createdAt' => 1), 'options' => array('expireAfterSeconds' => 60))
            //...
        );
    }

    // ...
}
?>

注意:expireAfterSeconds

然后,在任务期间应用索引。当您应用它时,将删除旧索引并创建新索引。

<?php
list($indexer, $dm) = DocumentManagerFactory::create($config);
$indexer->applyIndex();
?>

待办事项

  • 在配置中将 transform 方法 getProperties 转换
  • 为更复杂的服务监听器列表 preSave...
  • 更好的错误管理
  • 测试
  • 更好的文档