DbMongo.class.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | TOPThink [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. defined('THINK_PATH') or exit();
  12. /**
  13. * Mongo数据库驱动 必须配合MongoModel使用
  14. * @category Extend
  15. * @package Extend
  16. * @subpackage Driver.Db
  17. * @author liu21st <liu21st@gmail.com>
  18. */
  19. class DbMongo extends Db{
  20. protected $_mongo = null; // MongoDb Object
  21. protected $_collection = null; // MongoCollection Object
  22. protected $_dbName = ''; // dbName
  23. protected $_collectionName = ''; // collectionName
  24. protected $_cursor = null; // MongoCursor Object
  25. protected $comparison = array('neq'=>'ne','ne'=>'ne','gt'=>'gt','egt'=>'gte','gte'=>'gte','lt'=>'lt','elt'=>'lte','lte'=>'lte','in'=>'in','not in'=>'nin','nin'=>'nin');
  26. /**
  27. * 架构函数 读取数据库配置信息
  28. * @access public
  29. * @param array $config 数据库配置数组
  30. */
  31. public function __construct($config=''){
  32. if ( !class_exists('mongoClient') ) {
  33. throw_exception(L('_NOT_SUPPERT_').':mongoClient');
  34. }
  35. if(!empty($config)) {
  36. $this->config = $config;
  37. if(empty($this->config['params'])) {
  38. $this->config['params'] = array();
  39. }
  40. }
  41. }
  42. /**
  43. * 连接数据库方法
  44. * @access public
  45. */
  46. public function connect($config='',$linkNum=0) {
  47. if ( !isset($this->linkID[$linkNum]) ) {
  48. if(empty($config)) $config = $this->config;
  49. $host = 'mongodb://'.($config['username']?"{$config['username']}":'').($config['password']?":{$config['password']}@":'').$config['hostname'].($config['hostport']?":{$config['hostport']}":'').'/'.($config['database']?"{$config['database']}":'');
  50. try{
  51. $this->linkID[$linkNum] = new mongoClient( $host,$config['params']);
  52. }catch (MongoConnectionException $e){
  53. throw_exception($e->getmessage());
  54. }
  55. // 标记连接成功
  56. $this->connected = true;
  57. // 注销数据库连接配置信息
  58. if(1 != C('DB_DEPLOY_TYPE')) unset($this->config);
  59. }
  60. return $this->linkID[$linkNum];
  61. }
  62. /**
  63. * 切换当前操作的Db和Collection
  64. * @access public
  65. * @param string $collection collection
  66. * @param string $db db
  67. * @param boolean $master 是否主服务器
  68. * @return void
  69. */
  70. public function switchCollection($collection,$db='',$master=true){
  71. // 当前没有连接 则首先进行数据库连接
  72. if ( !$this->_linkID ) $this->initConnect($master);
  73. try{
  74. if(!empty($db)) { // 传人Db则切换数据库
  75. // 当前MongoDb对象
  76. $this->_dbName = $db;
  77. $this->_mongo = $this->_linkID->selectDb($db);
  78. }
  79. // 当前MongoCollection对象
  80. if(C('DB_SQL_LOG')) {
  81. $this->queryStr = $this->_dbName.'.getCollection('.$collection.')';
  82. }
  83. if($this->_collectionName != $collection) {
  84. N('db_read',1);
  85. // 记录开始执行时间
  86. G('queryStartTime');
  87. $this->_collection = $this->_mongo->selectCollection($collection);
  88. $this->debug();
  89. $this->_collectionName = $collection; // 记录当前Collection名称
  90. }
  91. }catch (MongoException $e){
  92. throw_exception($e->getMessage());
  93. }
  94. }
  95. /**
  96. * 释放查询结果
  97. * @access public
  98. */
  99. public function free() {
  100. $this->_cursor = null;
  101. }
  102. /**
  103. * 执行命令
  104. * @access public
  105. * @param array $command 指令
  106. * @return array
  107. */
  108. public function command($command=array()) {
  109. N('db_write',1);
  110. $this->queryStr = 'command:'.json_encode($command);
  111. // 记录开始执行时间
  112. G('queryStartTime');
  113. $result = $this->_mongo->command($command);
  114. $this->debug();
  115. if(!$result['ok']) {
  116. throw_exception($result['errmsg']);
  117. }
  118. return $result;
  119. }
  120. /**
  121. * 执行语句
  122. * @access public
  123. * @param string $code sql指令
  124. * @param array $args 参数
  125. * @return mixed
  126. */
  127. public function execute($code,$args=array()) {
  128. N('db_write',1);
  129. $this->queryStr = 'execute:'.$code;
  130. // 记录开始执行时间
  131. G('queryStartTime');
  132. $result = $this->_mongo->execute($code,$args);
  133. $this->debug();
  134. if($result['ok']) {
  135. return $result['retval'];
  136. }else{
  137. throw_exception($result['errmsg']);
  138. }
  139. }
  140. /**
  141. * 关闭数据库
  142. * @access public
  143. */
  144. public function close() {
  145. if($this->_linkID) {
  146. $this->_linkID->close();
  147. $this->_linkID = null;
  148. $this->_mongo = null;
  149. $this->_collection = null;
  150. $this->_cursor = null;
  151. }
  152. }
  153. /**
  154. * 数据库错误信息
  155. * @access public
  156. * @return string
  157. */
  158. public function error() {
  159. $this->error = $this->_mongo->lastError();
  160. trace($this->error,'','ERR');
  161. return $this->error;
  162. }
  163. /**
  164. * 插入记录
  165. * @access public
  166. * @param mixed $data 数据
  167. * @param array $options 参数表达式
  168. * @param boolean $replace 是否replace
  169. * @return false | integer
  170. */
  171. public function insert($data,$options=array(),$replace=false) {
  172. if(isset($options['table'])) {
  173. $this->switchCollection($options['table']);
  174. }
  175. $this->model = $options['model'];
  176. N('db_write',1);
  177. if(C('DB_SQL_LOG')) {
  178. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.insert(';
  179. $this->queryStr .= $data?json_encode($data):'{}';
  180. $this->queryStr .= ')';
  181. }
  182. try{
  183. // 记录开始执行时间
  184. G('queryStartTime');
  185. $result = $replace? $this->_collection->save($data): $this->_collection->insert($data);
  186. $this->debug();
  187. if($result) {
  188. $_id = $data['_id'];
  189. if(is_object($_id)) {
  190. $_id = $_id->__toString();
  191. }
  192. $this->lastInsID = $_id;
  193. }
  194. return $result;
  195. } catch (MongoCursorException $e) {
  196. throw_exception($e->getMessage());
  197. }
  198. }
  199. /**
  200. * 插入多条记录
  201. * @access public
  202. * @param array $dataList 数据
  203. * @param array $options 参数表达式
  204. * @return bool
  205. */
  206. public function insertAll($dataList,$options=array()) {
  207. if(isset($options['table'])) {
  208. $this->switchCollection($options['table']);
  209. }
  210. $this->model = $options['model'];
  211. N('db_write',1);
  212. try{
  213. // 记录开始执行时间
  214. G('queryStartTime');
  215. $result = $this->_collection->batchInsert($dataList);
  216. $this->debug();
  217. return $result;
  218. } catch (MongoCursorException $e) {
  219. throw_exception($e->getMessage());
  220. }
  221. }
  222. /**
  223. * 生成下一条记录ID 用于自增非MongoId主键
  224. * @access public
  225. * @param string $pk 主键名
  226. * @return integer
  227. */
  228. public function mongo_next_id($pk) {
  229. N('db_read',1);
  230. if(C('DB_SQL_LOG')) {
  231. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.find({},{'.$pk.':1}).sort({'.$pk.':-1}).limit(1)';
  232. }
  233. try{
  234. // 记录开始执行时间
  235. G('queryStartTime');
  236. $result = $this->_collection->find(array(),array($pk=>1))->sort(array($pk=>-1))->limit(1);
  237. $this->debug();
  238. } catch (MongoCursorException $e) {
  239. throw_exception($e->getMessage());
  240. }
  241. $data = $result->getNext();
  242. return isset($data[$pk])?$data[$pk]+1:1;
  243. }
  244. /**
  245. * 更新记录
  246. * @access public
  247. * @param mixed $data 数据
  248. * @param array $options 表达式
  249. * @return bool
  250. */
  251. public function update($data,$options) {
  252. if(isset($options['table'])) {
  253. $this->switchCollection($options['table']);
  254. }
  255. $this->model = $options['model'];
  256. N('db_write',1);
  257. $query = $this->parseWhere($options['where']);
  258. $set = $this->parseSet($data);
  259. if(C('DB_SQL_LOG')) {
  260. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.update(';
  261. $this->queryStr .= $query?json_encode($query):'{}';
  262. $this->queryStr .= ','.json_encode($set).')';
  263. }
  264. try{
  265. // 记录开始执行时间
  266. G('queryStartTime');
  267. if(isset($options['limit']) && $options['limit'] == 1) {
  268. $multiple = array("multiple" => false);
  269. }else{
  270. $multiple = array("multiple" => true);
  271. }
  272. $result = $this->_collection->update($query,$set,$multiple);
  273. $this->debug();
  274. return $result;
  275. } catch (MongoCursorException $e) {
  276. throw_exception($e->getMessage());
  277. }
  278. }
  279. /**
  280. * 删除记录
  281. * @access public
  282. * @param array $options 表达式
  283. * @return false | integer
  284. */
  285. public function delete($options=array()) {
  286. if(isset($options['table'])) {
  287. $this->switchCollection($options['table']);
  288. }
  289. $query = $this->parseWhere($options['where']);
  290. $this->model = $options['model'];
  291. N('db_write',1);
  292. if(C('DB_SQL_LOG')) {
  293. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.remove('.json_encode($query).')';
  294. }
  295. try{
  296. // 记录开始执行时间
  297. G('queryStartTime');
  298. $result = $this->_collection->remove($query);
  299. $this->debug();
  300. return $result;
  301. } catch (MongoCursorException $e) {
  302. throw_exception($e->getMessage());
  303. }
  304. }
  305. /**
  306. * 清空记录
  307. * @access public
  308. * @param array $options 表达式
  309. * @return false | integer
  310. */
  311. public function clear($options=array()){
  312. if(isset($options['table'])) {
  313. $this->switchCollection($options['table']);
  314. }
  315. $this->model = $options['model'];
  316. N('db_write',1);
  317. if(C('DB_SQL_LOG')) {
  318. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.remove({})';
  319. }
  320. try{
  321. // 记录开始执行时间
  322. G('queryStartTime');
  323. $result = $this->_collection->drop();
  324. $this->debug();
  325. return $result;
  326. } catch (MongoCursorException $e) {
  327. throw_exception($e->getMessage());
  328. }
  329. }
  330. /**
  331. * 查找记录
  332. * @access public
  333. * @param array $options 表达式
  334. * @return iterator
  335. */
  336. public function select($options=array()) {
  337. if(isset($options['table'])) {
  338. $this->switchCollection($options['table'],'',false);
  339. }
  340. $cache = isset($options['cache'])?$options['cache']:false;
  341. if($cache) { // 查询缓存检测
  342. $key = is_string($cache['key'])?$cache['key']:md5(serialize($options));
  343. $value = S($key,'','',$cache['type']);
  344. if(false !== $value) {
  345. return $value;
  346. }
  347. }
  348. $this->model = $options['model'];
  349. N('db_query',1);
  350. $query = $this->parseWhere($options['where']);
  351. $field = $this->parseField($options['field']);
  352. try{
  353. if(C('DB_SQL_LOG')) {
  354. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.find(';
  355. $this->queryStr .= $query? json_encode($query):'{}';
  356. $this->queryStr .= $field? ','.json_encode($field):'';
  357. $this->queryStr .= ')';
  358. }
  359. // 记录开始执行时间
  360. G('queryStartTime');
  361. $_cursor = $this->_collection->find($query,$field);
  362. if($options['order']) {
  363. $order = $this->parseOrder($options['order']);
  364. if(C('DB_SQL_LOG')) {
  365. $this->queryStr .= '.sort('.json_encode($order).')';
  366. }
  367. $_cursor = $_cursor->sort($order);
  368. }
  369. if(isset($options['page'])) { // 根据页数计算limit
  370. if(strpos($options['page'],',')) {
  371. list($page,$length) = explode(',',$options['page']);
  372. }else{
  373. $page = $options['page'];
  374. }
  375. $page = $page?$page:1;
  376. $length = isset($length)?$length:(is_numeric($options['limit'])?$options['limit']:20);
  377. $offset = $length*((int)$page-1);
  378. $options['limit'] = $offset.','.$length;
  379. }
  380. if(isset($options['limit'])) {
  381. list($offset,$length) = $this->parseLimit($options['limit']);
  382. if(!empty($offset)) {
  383. if(C('DB_SQL_LOG')) {
  384. $this->queryStr .= '.skip('.intval($offset).')';
  385. }
  386. $_cursor = $_cursor->skip(intval($offset));
  387. }
  388. if(C('DB_SQL_LOG')) {
  389. $this->queryStr .= '.limit('.intval($length).')';
  390. }
  391. $_cursor = $_cursor->limit(intval($length));
  392. }
  393. $this->debug();
  394. $this->_cursor = $_cursor;
  395. $resultSet = iterator_to_array($_cursor);
  396. if($cache && $resultSet ) { // 查询缓存写入
  397. S($key,$resultSet,$cache['expire'],$cache['type']);
  398. }
  399. return $resultSet;
  400. } catch (MongoCursorException $e) {
  401. throw_exception($e->getMessage());
  402. }
  403. }
  404. /**
  405. * 查找某个记录
  406. * @access public
  407. * @param array $options 表达式
  408. * @return array
  409. */
  410. public function find($options=array()){
  411. if(isset($options['table'])) {
  412. $this->switchCollection($options['table'],'',false);
  413. }
  414. $cache = isset($options['cache'])?$options['cache']:false;
  415. if($cache) { // 查询缓存检测
  416. $key = is_string($cache['key'])?$cache['key']:md5(serialize($options));
  417. $value = S($key,'','',$cache['type']);
  418. if(false !== $value) {
  419. return $value;
  420. }
  421. }
  422. $this->model = $options['model'];
  423. N('db_query',1);
  424. $query = $this->parseWhere($options['where']);
  425. $fields = $this->parseField($options['field']);
  426. if(C('DB_SQL_LOG')) {
  427. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.findOne(';
  428. $this->queryStr .= $query?json_encode($query):'{}';
  429. $this->queryStr .= $fields?','.json_encode($fields):'';
  430. $this->queryStr .= ')';
  431. }
  432. try{
  433. // 记录开始执行时间
  434. G('queryStartTime');
  435. $result = $this->_collection->findOne($query,$fields);
  436. $this->debug();
  437. if($cache && $result ) { // 查询缓存写入
  438. S($key,$result,$cache['expire'],$cache['type']);
  439. }
  440. return $result;
  441. } catch (MongoCursorException $e) {
  442. throw_exception($e->getMessage());
  443. }
  444. }
  445. /**
  446. * 统计记录数
  447. * @access public
  448. * @param array $options 表达式
  449. * @return iterator
  450. */
  451. public function count($options=array()){
  452. if(isset($options['table'])) {
  453. $this->switchCollection($options['table'],'',false);
  454. }
  455. $this->model = $options['model'];
  456. N('db_query',1);
  457. $query = $this->parseWhere($options['where']);
  458. if(C('DB_SQL_LOG')) {
  459. $this->queryStr = $this->_dbName.'.'.$this->_collectionName;
  460. $this->queryStr .= $query?'.find('.json_encode($query).')':'';
  461. $this->queryStr .= '.count()';
  462. }
  463. try{
  464. // 记录开始执行时间
  465. G('queryStartTime');
  466. $count = $this->_collection->count($query);
  467. $this->debug();
  468. return $count;
  469. } catch (MongoCursorException $e) {
  470. throw_exception($e->getMessage());
  471. }
  472. }
  473. public function group($keys,$initial,$reduce,$options=array()){
  474. $this->_collection->group($keys,$initial,$reduce,$options);
  475. }
  476. /**
  477. * 取得数据表的字段信息
  478. * @access public
  479. * @return array
  480. */
  481. public function getFields($collection=''){
  482. if(!empty($collection) && $collection != $this->_collectionName) {
  483. $this->switchCollection($collection,'',false);
  484. }
  485. N('db_query',1);
  486. if(C('DB_SQL_LOG')) {
  487. $this->queryStr = $this->_dbName.'.'.$this->_collectionName.'.findOne()';
  488. }
  489. try{
  490. // 记录开始执行时间
  491. G('queryStartTime');
  492. $result = $this->_collection->findOne();
  493. $this->debug();
  494. } catch (MongoCursorException $e) {
  495. throw_exception($e->getMessage());
  496. }
  497. if($result) { // 存在数据则分析字段
  498. $info = array();
  499. foreach ($result as $key=>$val){
  500. $info[$key] = array(
  501. 'name'=>$key,
  502. 'type'=>getType($val),
  503. );
  504. }
  505. return $info;
  506. }
  507. // 暂时没有数据 返回false
  508. return false;
  509. }
  510. /**
  511. * 取得当前数据库的collection信息
  512. * @access public
  513. */
  514. public function getTables(){
  515. if(C('DB_SQL_LOG')) {
  516. $this->queryStr = $this->_dbName.'.getCollenctionNames()';
  517. }
  518. N('db_query',1);
  519. // 记录开始执行时间
  520. G('queryStartTime');
  521. $list = $this->_mongo->listCollections();
  522. $this->debug();
  523. $info = array();
  524. foreach ($list as $collection){
  525. $info[] = $collection->getName();
  526. }
  527. return $info;
  528. }
  529. /**
  530. * set分析
  531. * @access protected
  532. * @param array $data
  533. * @return string
  534. */
  535. protected function parseSet($data) {
  536. $result = array();
  537. foreach ($data as $key=>$val){
  538. if(is_array($val)) {
  539. switch($val[0]) {
  540. case 'inc':
  541. $result['$inc'][$key] = (int)$val[1];
  542. break;
  543. case 'set':
  544. case 'unset':
  545. case 'push':
  546. case 'pushall':
  547. case 'addtoset':
  548. case 'pop':
  549. case 'pull':
  550. case 'pullall':
  551. $result['$'.$val[0]][$key] = $val[1];
  552. break;
  553. default:
  554. $result['$set'][$key] = $val;
  555. }
  556. }else{
  557. $result['$set'][$key] = $val;
  558. }
  559. }
  560. return $result;
  561. }
  562. /**
  563. * order分析
  564. * @access protected
  565. * @param mixed $order
  566. * @return array
  567. */
  568. protected function parseOrder($order) {
  569. if(is_string($order)) {
  570. $array = explode(',',$order);
  571. $order = array();
  572. foreach ($array as $key=>$val){
  573. $arr = explode(' ',trim($val));
  574. if(isset($arr[1])) {
  575. $arr[1] = $arr[1]=='asc'?1:-1;
  576. }else{
  577. $arr[1] = 1;
  578. }
  579. $order[$arr[0]] = $arr[1];
  580. }
  581. }
  582. return $order;
  583. }
  584. /**
  585. * limit分析
  586. * @access protected
  587. * @param mixed $limit
  588. * @return array
  589. */
  590. protected function parseLimit($limit) {
  591. if(strpos($limit,',')) {
  592. $array = explode(',',$limit);
  593. }else{
  594. $array = array(0,$limit);
  595. }
  596. return $array;
  597. }
  598. /**
  599. * field分析
  600. * @access protected
  601. * @param mixed $fields
  602. * @return array
  603. */
  604. public function parseField($fields){
  605. if(empty($fields)) {
  606. $fields = array();
  607. }
  608. if(is_string($fields)) {
  609. $fields = explode(',',$fields);
  610. }
  611. return $fields;
  612. }
  613. /**
  614. * where分析
  615. * @access protected
  616. * @param mixed $where
  617. * @return array
  618. */
  619. public function parseWhere($where){
  620. $query = array();
  621. foreach ($where as $key=>$val){
  622. if('_id' != $key && 0===strpos($key,'_')) {
  623. // 解析特殊条件表达式
  624. $query = $this->parseThinkWhere($key,$val);
  625. }else{
  626. // 查询字段的安全过滤
  627. if(!preg_match('/^[A-Z_\|\&\-.a-z0-9]+$/',trim($key))){
  628. throw_exception(L('_ERROR_QUERY_').':'.$key);
  629. }
  630. $key = trim($key);
  631. if(strpos($key,'|')) {
  632. $array = explode('|',$key);
  633. $str = array();
  634. foreach ($array as $k){
  635. $str[] = $this->parseWhereItem($k,$val);
  636. }
  637. $query['$or'] = $str;
  638. }elseif(strpos($key,'&')){
  639. $array = explode('&',$key);
  640. $str = array();
  641. foreach ($array as $k){
  642. $str[] = $this->parseWhereItem($k,$val);
  643. }
  644. $query = array_merge($query,$str);
  645. }else{
  646. $str = $this->parseWhereItem($key,$val);
  647. $query = array_merge($query,$str);
  648. }
  649. }
  650. }
  651. return $query;
  652. }
  653. /**
  654. * 特殊条件分析
  655. * @access protected
  656. * @param string $key
  657. * @param mixed $val
  658. * @return string
  659. */
  660. protected function parseThinkWhere($key,$val) {
  661. $query = array();
  662. switch($key) {
  663. case '_query': // 字符串模式查询条件
  664. parse_str($val,$query);
  665. if(isset($query['_logic']) && strtolower($query['_logic']) == 'or' ) {
  666. unset($query['_logic']);
  667. $query['$or'] = $query;
  668. }
  669. break;
  670. case '_string':// MongoCode查询
  671. $query['$where'] = new MongoCode($val);
  672. break;
  673. }
  674. return $query;
  675. }
  676. /**
  677. * where子单元分析
  678. * @access protected
  679. * @param string $key
  680. * @param mixed $val
  681. * @return array
  682. */
  683. protected function parseWhereItem($key,$val) {
  684. $query = array();
  685. if(is_array($val)) {
  686. if(is_string($val[0])) {
  687. $con = strtolower($val[0]);
  688. if(in_array($con,array('neq','ne','gt','egt','gte','lt','lte','elt'))) { // 比较运算
  689. $k = '$'.$this->comparison[$con];
  690. $query[$key] = array($k=>$val[1]);
  691. }elseif('like'== $con){ // 模糊查询 采用正则方式
  692. $query[$key] = new MongoRegex("/".$val[1]."/");
  693. }elseif('mod'==$con){ // mod 查询
  694. $query[$key] = array('$mod'=>$val[1]);
  695. }elseif('regex'==$con){ // 正则查询
  696. $query[$key] = new MongoRegex($val[1]);
  697. }elseif(in_array($con,array('in','nin','not in'))){ // IN NIN 运算
  698. $data = is_string($val[1])? explode(',',$val[1]):$val[1];
  699. $k = '$'.$this->comparison[$con];
  700. $query[$key] = array($k=>$data);
  701. }elseif('all'==$con){ // 满足所有指定条件
  702. $data = is_string($val[1])? explode(',',$val[1]):$val[1];
  703. $query[$key] = array('$all'=>$data);
  704. }elseif('between'==$con){ // BETWEEN运算
  705. $data = is_string($val[1])? explode(',',$val[1]):$val[1];
  706. $query[$key] = array('$gte'=>$data[0],'$lte'=>$data[1]);
  707. }elseif('not between'==$con){
  708. $data = is_string($val[1])? explode(',',$val[1]):$val[1];
  709. $query[$key] = array('$lt'=>$data[0],'$gt'=>$data[1]);
  710. }elseif('exp'==$con){ // 表达式查询
  711. $query['$where'] = new MongoCode($val[1]);
  712. }elseif('exists'==$con){ // 字段是否存在
  713. $query[$key] =array('$exists'=>(bool)$val[1]);
  714. }elseif('size'==$con){ // 限制属性大小
  715. $query[$key] =array('$size'=>intval($val[1]));
  716. }elseif('type'==$con){ // 限制字段类型 1 浮点型 2 字符型 3 对象或者MongoDBRef 5 MongoBinData 7 MongoId 8 布尔型 9 MongoDate 10 NULL 15 MongoCode 16 32位整型 17 MongoTimestamp 18 MongoInt64 如果是数组的话判断元素的类型
  717. $query[$key] =array('$type'=>intval($val[1]));
  718. }else{
  719. $query[$key] = $val;
  720. }
  721. return $query;
  722. }
  723. }
  724. $query[$key] = $val;
  725. return $query;
  726. }
  727. }