YiiMongoDbSuite, Yii Mongo DB Active Record 扩展

分享于 

18分钟阅读

GitHub

  繁體 雙語
Yii Mongo DB Active Record extension
  • 源代码名称:YiiMongoDbSuite
  • 源代码网址:http://www.github.com/canni/YiiMongoDbSuite
  • YiiMongoDbSuite源代码文档
  • YiiMongoDbSuite源代码下载
  • Git URL:
    git://www.github.com/canni/YiiMongoDbSuite.git
    Git Clone代码到本地:
    git clone http://www.github.com/canni/YiiMongoDbSuite
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/canni/YiiMongoDbSuite
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    

    这个扩展是一个几乎完全完成的ActiveRecord支持 MongoDB,它最初是由 tyohan插件编写的,用于修复一些主要的Bug,并为MongoDB开发者添加完整的功能套件。

    重要信息:我已经开发了这个扩展作为一个业余爱好项目。 现在我已经不再在我的爱好和工作项目中使用 Yii。 我不再维护这里代码。 我的代码库可以在github上轻松的fork/下载。 可以继续我的工作,YMDS已经有活跃的社区,你可以在google组( 描述波形) 中找到支持。

    Flattr this

    请参考新的完整文档页面

    注释提供的这个扩展中使用 OR 操作符

    这是 1.3.6版本

    在这里版本中添加了 :

    • 少量恼人的Bug 固定
    • 文档更正
    • 添加了 EMongoPartialDocument 类,支持来自 DB的文档的完整部分加载
    • 添加了额外的设备管理器,可以取代Yii默认版本,并使用Mongo模型
    • 完成大量的[advanced.partial-batch-update]的能力

    关键功能列表:

    来自标准 Yii ActiveRecord实现的特性覆盖

    • using ( ) -> find/findAll/count/countByAttributes 和其他 Yii ActiveRecord语法的支持
    • 命名作用域以及默认范围和参数化作用域,就像在AR中一样
    • 可以使用out-of-box高效 DataProvider DataProvider使用原生 php db驱动程序排序。限制和偏移功能来返回结果 !
    • 模型类和嵌入文档继承自 CModel,因此你可以使用每个可以处理CModel的类( IE: 窗体生成器)
    • 关系支持 idea/concept/example
    • 为EMongoDocument模型生成CRUD模型的支持,Gii
    • 从 exist SQL表中为生成mongo文档模型提供 !
    • 很容易使用标准对象,你不必创建复杂的MongoDB查询数组 !

    相关功能列表

    • 通过Yii标准规则和验证功能支持架构较少的文档
    • 嵌入/嵌套文档支持( 嵌入文档具有自己的模型类和它们自己的规则和其他方法)
    • ( 几乎只能限制 MongoDB 4MB 文档的限制) 无限文档嵌入/嵌套
    • 延迟加载/创建嵌入式文档
    • 能够在不同范围。全局。模型级别和单个模型对象上设置DB写操作的FSync和/或者安全标志。
    • 使用有效的MongoDB游标而不是原始的结果数组( 由findAll的方法返回)的能力,
    • MongoDB GridFS功能支持,感谢你的支持: and和 Philippe Gaultier
    • 支持使用_id字段以外的任何其他键作为集合的主键
    • 支持在单个集合中具有不同的模型 !
    • 集合的自动高效索引定义,每个模型
    • 支持"柔和"文档,没有固定属性列表的文档
    • 使用MongoDB运算符/功能,可以进行 Extreme 文档部分更新的能力
    • 支持以下版本的PHP Mongo驱动程序版本 1.0.5
    • 支持从数据库部分加载文档

    的限制:

    • 主要限制只是MongoDB本身的那些,比如 4mb 个数据传输限制。 但这也不是一个大问题。
    • 在当前的incarnation中,这里扩展不适用于"$or"标准运算符。 当我们完成工作时,我们将删除这一行并添加一个示例。

    重要:GitHub的版本是最新的,因为补丁被推到项目中。 这可能会定期得到更新,也可能不会得到更新。

    要求

    • Yii 1.1.5是必需
    • 建议使用MongoDB最新的稳定性。 未测试过的旧版本。

    设置

    在 protected/config/main.php 配置文件中。 注释掉( 或者删除) components中的数据库当前的'数据库'array,然后将以下内容添加到 file:

    
    [php]
    
    
    
     'import' => array(
    
    
    . . .
    
    
     'ext.YiiMongoDbSuite.*',
    
    
     ),
    
    
    
     'components' => array(
    
    
    . . .
    
    
     'mongodb' => array(
    
    
     'class' => 'EMongoDB',
    
    
     'connectionString' => 'mongodb://localhost',
    
    
     'dbName' => 'myDatabaseName',
    
    
     'fsyncFlag' => true,
    
    
     'safeFlag' => true,
    
    
     'useCursor' => false
    
    
     ),
    
    
     ),
    
    
    
    
    
    • ConnectionString:'localhost'应该更改为连接主机的主机的ip或者主机名。 例如如果连接到服务器,它可能是 'connectionString' => 'mongodb://username@xxx.xx.xx.xx' 其中 xx.xx. xx.xx 是网络服务器或者主机的ip ( 或者主机名)。
    • dbName: 你希望收藏集中存储的NAME。 数据库名称。
    • 如果将fsyncFlag设置为 true,这使得mongodb确保所有对数据库的写入都安全地存储到磁盘。 ( 默认为 true )
    • 如果safeFlag设置为 true,mongodb将等待检索所有写操作的状态,并检查是否一切正常。 ( 默认为 true )
    • 如果useCursors设置为 true,扩展将返回EMongoCursor而不是原始预先填充的数组,形成findAll*方法( 默认为 false )。

    这就是你所要做的。 你可以像 Active Record 一样使用它。 例如:

    
    [php]
    
    
    
     $client = new Client();
    
    
     $client->first_name='something';
    
    
     $client->save();
    
    
     $clients = Client::model()->findAll();
    
    
    
    
    

    基本用法

    只需定义以下模型:

    
    [php]
    
    
    
     class User extends EMongoDocument
    
    
     {
    
    
     public $login;
    
    
     public $name;
    
    
     public $pass;
    
    
    
    //This has to be defined in every model, this is same as with standard Yii ActiveRecord
    
    
     public static function model($className=__CLASS__)
    
    
     {
    
    
     return parent::model($className);
    
    
     }
    
    
    
    //This method is required!
    
    
     public function getCollectionName()
    
    
     {
    
    
     return 'users';
    
    
     }
    
    
    
     public function rules()
    
    
     {
    
    
     return array(
    
    
     array('login, pass', 'required'),
    
    
     array('login, pass', 'length', 'max' => 20),
    
    
     array('name', 'length', 'max' => 255),
    
    
     );
    
    
     }
    
    
    
     public function attributeLabels()
    
    
     {
    
    
     return array(
    
    
     'login' => 'User Login',
    
    
     'name' => 'Full name',
    
    
     'pass' => 'Password',
    
    
     );
    
    
     }
    
    
     }
    
    
    
    
    

    就是这样现在开始使用这个用户模型类,像标准的Yii AR模型 !

    嵌入文档

    注意:出于性能原因,嵌入式文档应该从EMongoEmbeddedDocument扩展而不是从 EMongoDocument

    EMongoEmbeddedDocument几乎与EMongoDocument一样,实际上EMongoDocument从EMongoEmbeddedDocument扩展,并添加到它的数据库连接相关的。

    注:嵌入式文档不应该有 static model() 方法 !

    所以如果你有 User.php 模型和一个 UserAddress.php 模型,它是嵌入式文档。 假设我们有以下嵌入文档:

    
    [php]
    
    
    
     class UserAddress extends EMongoEmbeddedDocument
    
    
     {
    
    
     public $city;
    
    
     public $street;
    
    
     public $house;
    
    
     public $apartment;
    
    
     public $zip;
    
    
    
     public function rules()
    
    
     {
    
    
     return array(
    
    
     array('city, street, house', 'length', 'max'=>255),
    
    
     array('house, apartment, zip', 'length', 'max'=>10),
    
    
     );
    
    
     }
    
    
    
     public function attributeLabels()
    
    
     {
    
    
     return array(
    
    
     'zip'=>'Postal Code',
    
    
     );
    
    
     }
    
    
     }
    
    
    
    
    

    现在,我们可以从上一节中将这里方法添加到用户模型中:

    
    [php]
    
    
    
     class User extends EMongoDocument {
    
    
    . . .
    
    
    
     public function embeddedDocuments()
    
    
     {
    
    
     return array(
    
    
    //property name => embedded document class name
    
    
     'address'=>'UserAddress'
    
    
     );
    
    
     }
    
    
    
    . . .
    
    
     }
    
    
    
    
    

    使用它就像馅饼一样简单 !

    
    [php]
    
    
    
     $client = new Client;
    
    
     $client->address->city='New York';
    
    
     $client->save();
    
    
    
    
    

    它将自动调用模型和所有嵌入文档的验证 ! 你甚至可以嵌套嵌入文档在嵌入文档中,只需使用另一个嵌入文档的array 定义 embeddedDocuments() 方法重要: 这里机制使用 recurrency,并且不会处理循环嵌套,你必须小心使用这里特性:

    数组

    你可以轻松地在数据库中存储数组 !

    简单数组

    • 定义 array的属性,并在其中存储 array。

    的嵌入式文档

    • ( 我知道) 不可以能在哪里轻松地为这个机制提供机制,你必须编写自己的机制。
    • 这是我现在完成的方式:
    
    [php]
    
    
    
    //add a property for your array of embedded documents
    
    
     public $addresses;
    
    
    
    //add EmbeddedArraysBehavior
    
    
     public function behaviors()
    
    
     {
    
    
     return array(
    
    
     array(
    
    
     'class'=>'ext.YiiMongoDbSuite.extra.EEmbeddedArraysBehavior',
    
    
     'arrayPropertyName'=>'addresses',//name of property
    
    
     'arrayDocClassName'=>'ClientAddress'//class name of documents in array
    
    
     ),
    
    
     );
    
    
     }
    
    
    
    
    

    所以对于用户,如果你希望他们能够保存多个地址,你可以执行以下操作:

    
    [php]
    
    
    
     $c = new Client;
    
    
     $c->addresses[0] = new ClientAddress;
    
    
     $c->addresses[0]->city='NY';
    
    
     $c->save();//behavior will handle validation of array too
    
    
    
    
    

    或者

    
    [php]
    
    
    
     $c = Client::model()->find();
    
    
     foreach($c->addresses as $addr)
    
    
     {
    
    
     echo $addr->city;
    
    
     }
    
    
    
    
    

    查询

    这是让这个扩展变得非常重要的事情之一。 查询需要的对象是非常容易的。

    
    [php]
    
    
    
    //simple find first. just like normal AR.
    
    
     $object = ModelClass::model()->find()
    
    
    
    
    

    现在假设你只想检索用户,它的状态为 1 ( 活动的)。 有一个对象就是这样,使得查询变得容易。

    
    [php]
    
    
    
     $c = new EMongoCriteria;
    
    
     $c->status('==', 1);
    
    
     $users = ModelClass::model->findAll($c);
    
    
    
    
    

    现在 $users 将是所有用户的array,它的文档中的状态键为 1. 这是一个只列出活跃用户的好方法。 那是什么你只想显示 10个最近激活的用户? 太容易了。

    
    [php]
    
    
    
     $c = new EMongoCriteria;
    
    
     $c->active('==', 1)->limit(10);
    
    
    
     $users = ModelClass::model->findAll($c);
    
    
    
    
    

    这很容易。为了代替'等于'键,你可以使用以下任何操作符

    
    
    
    
    
     - 'greater' |> 
    
    
     - 'greaterEq' |> =
    
    
     - 'less' | <
    
    
     - 'lessEq' | <=
    
    
     - 'notEq' |!=, <>
    
    
     - 'in' | 
    
    
     - 'notIn' | 
    
    
     - 'all' | 
    
    
     - 'size' | 
    
    
     - 'exists' | 
    
    
     - 'type' |//BSON type see mongodb docs for this
    
    
     - 'notExists' | 
    
    
     - 'mod' | %
    
    
     - 'equals' | ==
    
    
     - 'where' |//JavaScript operator
    
    
    
    
    

    *NOTICE: 更新版本中的$or 运算符不能用这个扩展操作。 如果 fixed.Newer db的版本将工作,那么我们将把它添加到列表中,而不是 $or 操作符。 例如使用这些操作符有效地使用这些操作符,可以使用这里的操作符文档。

    以下是使用条件的几个示例:

    
    [php]
    
    
    
    //first you must create a new criteria object
    
    
     $criteria = new EMongoCriteria;
    
    
    
    //find the single user with the personal_number == 12345
    
    
     $criteria->personal_number('==', 12345);
    
    
    //OR like this:
    
    
     $criteria->personal_number = 12345; 
    
    
    
     $user = User::model->find($criteria);
    
    
    
    //find all users in New York. This will search in the embedded document of UserAddress
    
    
     $criteria->address->city('==', 'New York');
    
    
    //Or
    
    
     $criteria->address->city = 'New York';
    
    
     $users = User::model()->findAll($criteria);
    
    
    
    //Ok now try this. Only active users, only show at most 10 users, and sort by first name, descending, and offset by 20 (pagination):
    
    
    //note the sort syntax. it must have an array value and use the => syntax.
    
    
     $criteria->status('==', 1)->limit(10)->sort(array('firstName' => EMongoCriteria::SORT_DESC))->offset(20);
    
    
     $users = User::model()->findAll($criteria);
    
    
    
    //A more advanced case. All users with a personal_number evenly divisible by 10, sorted by first name ascending, limit 10 users, offset by 25 users (pagination), and remove any address fields from the returned result.
    
    
     $criteria->personal_number('%', array(10, 0))//modulo => personal_number % 10 == 0
    
    
     ->sort(array('firstName' => EMongoCriteria::SORT_ASC))
    
    
     ->limit(10)
    
    
     ->offset(25);
    
    
     $users = User::model()->findAll($criteria);
    
    
    
    //You can even use the where operator with javascript like so:
    
    
     $criteria->fieldName('where', ' expression in javascript ie: this.field> this.field2');
    
    
    //but remember that this kind of query is a bit slower than normal finds.
    
    
    
    
    

    正则表达式/sql像 replacemt

    你可以使用本机PHP驱动程序类MongoRegex来查询:

    
    [php]
    
    
    
    //Create criteria
    
    
     $criteria = new EMongoCriteria;
    
    
    //Find all records witch have first name starring on a, b and c, case insensitive search
    
    
     $criteria->first_name = new MongoRegex('/[abc].*/i');
    
    
     $clients = Client::model()->findAll($criteria);
    
    
    //see phpdoc for MongoRegex class for more examples
    
    
    
    
    

    有关如何使用查询 array的参考,请参阅: http://www.php.net/manual/en/mongocollection.find.php

    从 array 创建标准对象:

    
    [php]
    
    
    
    //Example criteria
    
    
     $array = array(
    
    
     'conditions'=>array(
    
    
    //field name => operator definition
    
    
     'FieldName1'=>array('greaterEq' => 10),//Or 'FieldName1'=>array('>=', 10)
    
    
     'FieldName2'=>array('in' => array(1, 2, 3)),
    
    
     'FieldName3'=>array('exists'),
    
    
     ),
    
    
     'limit'=>10,
    
    
     'offset'=>25,
    
    
     'sort'=>array('fieldName1'=>EMongoCriteria::SORT_ASC, 'fieldName4'=>EMongoCriteria::SORT_DESC),
    
    
     );
    
    
     $criteria = new EMongoCriteria($array);
    
    
    //or
    
    
     $clients = ClientModel::model()->findAll($array);
    
    
    
    
    

    已知的Bug

    • 记住,这还没有完成。 所以在这个阶段,它可以有一些;]
    • 如果你发现任何消息请告诉我
    • 如前所述,它不能与或者运算符一起使用

    资源

    需要 !

    • 我不是英语母语者,需要有人可以 correct/rewrite/write 我的文档和/或者phpdoc代码
    • 任何帮助都将是伟大的:
    • 与我联系:darek.krk 点或者通过 PM

    非常感谢:

    • tyohan: 关于扩展的第一个启发和概念
    • luckysmack: 用于测试和文档的大帮助
    • Jose和 Philippe Gaultier,用于实现和共享GridFS支持
    • Nagy Attila Gábor,用于新功能和测试的大帮助

    ext  act  mongo  记录  Active  YII  
    相关文章