{"action":"opened","issue":{"url":"https://api.github.com/repos/fred-ye/summary/issues/40","labels_url":"https://api.github.com/repos/fred-ye/summary/issues/40/labels{/name}","comments_url":"https://api.github.com/repos/fred-ye/summary/issues/40/comments","events_url":"https://api.github.com/repos/fred-ye/summary/issues/40/events","html_url":"https://github.com/fred-ye/summary/issues/40","id":53304114,"number":40,"title":"MongoDB与Yii搭建API－1","user":{"login":"fred-ye","id":6369935,"avatar_url":"https://avatars.githubusercontent.com/u/6369935?v=3","gravatar_id":"","url":"https://api.github.com/users/fred-ye","html_url":"https://github.com/fred-ye","followers_url":"https://api.github.com/users/fred-ye/followers","following_url":"https://api.github.com/users/fred-ye/following{/other_user}","gists_url":"https://api.github.com/users/fred-ye/gists{/gist_id}","starred_url":"https://api.github.com/users/fred-ye/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fred-ye/subscriptions","organizations_url":"https://api.github.com/users/fred-ye/orgs","repos_url":"https://api.github.com/users/fred-ye/repos","events_url":"https://api.github.com/users/fred-ye/events{/privacy}","received_events_url":"https://api.github.com/users/fred-ye/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-01-03T13:26:19Z","updated_at":"2015-01-03T13:26:19Z","closed_at":null,"body":"## MongoDB与Yii搭建API－1\r\n在上一个项目中，我们采用MongoDB和Yii框架来为手机端提供API，那是我第一次采用学习并采用Yii来开发项目，确实深刻的体会到Yii的便捷和高效。代码写起来感觉非常的清晰，今天来对上一个项目里面的东西进行总结一下。主要是总结MongoDB和Yii的操作，当然也会写一些边边角角的东西。当前是采用Yii 1.1, MongoDB的扩展是1.3.6\r\n\r\n###如何整合\r\n1. 首先需在配置php对mongodb的扩展，此处就不说了。然后我们需要mongodb对yii的扩展，将相关代码拷到Yii应用的 `protected/extensions`目录下。\r\n2. 在Yii应用的`config/main.php`中引入mongodb的扩展并配置连接参数，如下:\r\n>\r\n```\r\n    'import'=>array(\r\n        'application.models.*',\r\n        'application.components.*',\r\n        'ext.mongo.*',\r\n    ),\r\n    'components' => array(\r\n      ...\r\n         'mongodb'=>array(\r\n             'class' => 'EMongoDB' ,\r\n             'connectionString' => 'mongodb://irunning:abc123_@localhost:27017/irunning',\r\n             'dbName' => 'irunning',\r\n             'fsyncFlag' => true,\r\n             'safeFlag'=>true,\r\n             'useCursor'=>false,\r\n         ),\r\n   ）\r\n```\r\n到此，我们的配置便完成了，接着就可以开始使用Yii和MongoDB\r\n\r\n### Yii操作MongoDB\r\n#### Model定义\r\n我们先定义一个`BaseModel`, 在这个`Model`中定义部分公共的属性。如下:\r\n\r\n```\r\n<?php\r\nclass BaseModel extends EMongoDocument\r\n{\r\n    public $_id;\r\n    public $created_time;\r\n    public $updated_time;\r\n    public $deleted;\r\n    public static function model($className=__CLASS__)\r\n    {\r\n        return parent::model($className);\r\n    }\r\n    public function getCollectionName()\r\n    {\r\n        return null;\r\n    }\r\n    public function rules()\r\n    {\r\n        return array(\r\n            array('_id', 'default', 'value' => new MongoId()),\r\n            array('deleted', 'default', 'value' => Constant::UNDELETE),\r\n            array('created_time', 'default', 'value' => new MongoDate()),\r\n            array('updated_time', 'default', 'value' => new MongoDate()),\r\n        );\r\n    }\r\n    public function attributeLabels()\r\n    {\r\n    }\r\n\r\n```\r\n\r\n\r\n然后，我们来定义一个实际会使用的Model--> `User`. \r\n\r\n```\r\nclass User extends BaseModel {\r\n\tpublic $name;\r\n\tpublic $password;\r\n\tpublic $nickname;\r\n\tpublic $email;\r\n\tpublic $height;\r\n\tpublic $weight;\r\n\tpublic $gender;\r\n\tpublic $register_time;\r\n\tpublic $last_login_time;\r\n\t\r\n\tpublic static function model($className=__CLASS__) {\r\n        return parent::model($className);\r\n    }\r\n\r\n\r\n    /**\r\n     * @return string the associated collection name\r\n     */\r\n    public function getCollectionName() {\r\n        return 'user';\r\n    }\r\n    \r\n    public function rules() {\r\n        return  array_merge(parent::rules(), array(\r\n        \t...\r\n        ));\r\n    ｝\r\n}\r\n\r\n``` \r\n\r\n定义好了`Model`之后，我们可以像操作其它`AR`一样来操作了。\r\n\r\n#### 对MongoDB的操作\r\n对MongoDB的操作是通过`Model`来完成的。在`EmongoDocument`中定义了不少操作DB的方法，如:\r\n\r\n* findByPk($userId, $criteria)\r\n* save\r\n* update\r\n* delete\r\n* ......\r\n>\r\n```php\r\n$user = new User();\r\n$user->_id = new MongoId();\r\n$user->name = \"user1\";\r\n......\r\n$user->save();\r\n```\r\n\r\n##### EmongoCriteria的使用\r\n`EmongoCriteria`是用来封装条件的,在我们进行CRUD操作时都会使用到，需要掌握好。其使用方式如下：\r\n第一种方式是使用`array`来指定查询条件:\r\n\r\n```\r\n//指定查询条件\r\n$condition = array(\r\n\t'name'=>$username,\r\n);\r\n//new 一个EmongoCriteria实例\r\n$criteria = new EmongoCriteria();\r\n//将查询条件设定到criteria中。\r\n$criteria->setConditions($condition);\r\n//用model执行find方法。\r\n$user = User::model->find($criteria);\r\n\r\n```\r\n\r\n另一种方式是直接对`EmongoCriteria`添加条件，如下:\r\n\r\n```\r\n$criteria = new EmongoCriteria();\r\n$criteria->select(array('name', 'age', 'password')); //指定查询的列\r\n$criteria->addCond('name', '==', $username);\r\n//$criteria->name = $username;当然也可以这么写，和上一行的效果是一样的\r\n//条件是可以不断追加的\r\n$criteria->addCond('deleted', '==', 0);\r\n$criteria->addCond('start_time', '>=', $startTime);\r\n$criteria->addCond('start_time', '<', $endTime);\r\n\r\n//用model执行find方法。\r\n$user = User::model->find($criteria);\r\n```\r\n\r\n1.多个条件的组合。例如我要查询用户名是'user1',age是18的用户，只需要将上面的$condition稍做修改即可:\r\n\r\n```\r\n$condition = array(\r\n\t'name'=>'user1',\r\n\t'age'=> 18\r\n);\r\n```\r\n\r\n2.如果是表示**或**的关系\r\n\r\n```\r\n$condition = array(\r\n\t'$or' => array(\r\n\t\t'age' => 18,\r\n\t\t'age' => 28\r\n\t)\r\n)\r\n```\r\n\r\n3.分页和排序\r\n\r\n分页和排序的操作也是非常的简单，只要在`$criteria`对象上接着添加方法便好\r\n\r\n```\r\n$criteria->setLimit($pageSize);//每页多少条数目\r\n$criteria->setOffset($startIndex); //起始位置\r\n$criteria->setSort(array('start_time'=>EMongoCriteria::SORT_DESC));\r\n```\r\n如果是采用`array`来指定分页和排序的参数，要注意`array`的层次结构。以下使用一个官方的例子\r\n\r\n```\r\n$array = array(\r\n    'conditions'=>array(\r\n        // field name => operator definition\r\n        'FieldName1'=>array('greaterEq' => 10), // Or 'FieldName1'=>array('>=', 10)\r\n        'FieldName2'=>array('in' => array(1, 2, 3)),\r\n        'FieldName3'=>array('exists'),\r\n    ),\r\n    'limit'=>10,\r\n    'offset'=>25,\r\n    'sort'=>array('fieldName1'=>EMongoCriteria::SORT_ASC,\r\n                  'fieldName4'=>EMongoCriteria::SORT_DESC),\r\n);\r\n$criteria = new EMongoCriteria($array);\r\n$user = User::model()->find($criteria);\r\n\r\n```\r\n\r\n4.统计数量`User::model()->count($criteria)`\r\n\r\n"}}