├── LICENSE ├── README.md └── application ├── config └── mongo_db.php └── libraries └── Mongo_db.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Intekhab Rizvi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CIMongo - MongoDB Library for Codeigniter 3 - Supports PHP 7+, Codeigniter 3+, mognodb-1.5.x extension 2 | ======= 3 | 4 | This library help you to use perform MongoDB based queries just like active record in CodeIgniter. 5 | 6 | This library support 7 | * Write Concern and Journal 8 | * Read Preference 9 | * Aggregation Framework 10 | * Query Profiling 11 | 12 | Wiki and how-to can be found here http://intekhabrizvi.github.io/mongodb-library-for-codeigniter.html 13 | 14 | For Code Unitesting use branch named `unitesting` 15 | # Methods 16 | 17 | ## Insert Method 18 | * `insert` Insert a new document into a collection 19 | * `batch_insert` Insert multiple new documents into a collection 20 | 21 | ## Select Method 22 | * `select` Get select fields from returned documents 23 | * `where` OR `get_where` Where section of the query 24 | * `where_in` Where something is in an array of something 25 | * `where_in_all` Where something is in all of an array of * something 26 | * `where_not_in` Where something is not in array of something 27 | * `where_or` Where something is based on or 28 | * `where_gt` Where something is greater than something 29 | * `where_gte` Where something is greater than or equal to something 30 | * `where_lt` Where something is less than something 31 | * `where_lte` Where something is less than or equal to something 32 | * `where_between` Where something is in between to something 33 | * `where_between_ne` Where something is in between and but not equal to something 34 | * `where_ne` Where something is not equal to something 35 | * `like` Where something is search by like query 36 | * `order_by` Order the results 37 | * `limit` OR `offset` Limit the number of returned results 38 | * `count` Document Count based on where query 39 | * `distinct` Retrieve a list of distinct values for the given key across a single collection 40 | * `find_one` Retrieve single document from collection 41 | 42 | ## Update Method 43 | * `set` Sets a field to a value 44 | * `unset_field` Unsets a field 45 | * `addtoset` Adds a value to an array if doesn't exist 46 | * `push` Pushes a value into an array field 47 | * `pop` Pops a value from an array field 48 | * `pull` Removes an array by the value of a field 49 | * `rename_field` Rename a field 50 | * `inc` Increments the value of a field 51 | * `mul` Multiple the value of a field 52 | * `max` Updates the value of the field to a specified value if the specified value is greater than the current value of the field 53 | * `min` Updates the value of the field to a specified value if the specified value is less than the current value of the field. 54 | * `update` Update a single document in a collection 55 | * `update_all` Update all documents in a collection 56 | 57 | ## Delete Method 58 | * `delete` Delete a single document in a collection 59 | * `delete_all` Delete all documents in a collection 60 | 61 | ## Aggregation Method 62 | * `aggregate` Perform aggregation query on document 63 | 64 | ## Profiling Methods 65 | * `output_benchmark` return complete explain data for all the find based query performed 66 | 67 | ## Index Method 68 | * `add_index` Create a new index on collection 69 | * `remove_index` Remove index from collection 70 | * `list_indexes` Show all index created on collections 71 | 72 | ## DB Method 73 | * `switch_db` Switch to a different database 74 | * `drop_db` Drops a database 75 | * `drop_collection` Drops a collection 76 | * `command` Perform MongoDB command 77 | 78 | ## Extra Helper 79 | * `date` Create or convert date to MongoDB based Date 80 | 81 | ## License 82 | MIT. 83 | Codes are provided AS IS basis, i am not responsible for anything. 84 | -------------------------------------------------------------------------------- /application/config/mongo_db.php: -------------------------------------------------------------------------------- 1 | CI =& get_instance(); 63 | $this->CI->load->config('mongo_db'); 64 | $this->config = $this->CI->config->item('mongo_db'); 65 | $this->param = $param; 66 | $this->connect(); 67 | } 68 | 69 | /** 70 | * -------------------------------------------------------------------------------- 71 | * Class Destructor 72 | * -------------------------------------------------------------------------------- 73 | * 74 | * Close all open connections. 75 | */ 76 | function __destruct() 77 | { 78 | if(is_object($this->connect)) 79 | { 80 | //$this->connect->close(); 81 | } 82 | } 83 | 84 | /** 85 | * -------------------------------------------------------------------------------- 86 | * Prepare configuration for mongoDB connection 87 | * -------------------------------------------------------------------------------- 88 | * 89 | * Validate group name or autoload default group name from config file. 90 | * Validate all the properties present in config file of the group. 91 | */ 92 | 93 | private function prepare() 94 | { 95 | if(is_array($this->param) && count($this->param) > 0 && isset($this->param['activate']) == TRUE) 96 | { 97 | $this->activate = $this->param['activate']; 98 | } 99 | else if(isset($this->config['active']) && !empty($this->config['active'])) 100 | { 101 | $this->activate = $this->config['active']; 102 | }else 103 | { 104 | show_error("MongoDB configuration is missing.", 500); 105 | } 106 | 107 | if(isset($this->config[$this->activate]) == TRUE) 108 | { 109 | if(empty($this->config[$this->activate]['hostname'])) 110 | { 111 | show_error("Hostname missing from mongodb config group : {$this->activate}", 500); 112 | } 113 | else 114 | { 115 | $this->hostname = trim($this->config[$this->activate]['hostname']); 116 | } 117 | 118 | if(empty($this->config[$this->activate]['port'])) 119 | { 120 | show_error("Port number missing from mongodb config group : {$this->activate}", 500); 121 | } 122 | else 123 | { 124 | $this->port = trim($this->config[$this->activate]['port']); 125 | } 126 | 127 | if(isset($this->config[$this->activate]['no_auth']) == FALSE 128 | && empty($this->config[$this->activate]['username'])) 129 | { 130 | show_error("Username missing from mongodb config group : {$this->activate}", 500); 131 | } 132 | else 133 | { 134 | $this->username = trim($this->config[$this->activate]['username']); 135 | } 136 | 137 | if(isset($this->config[$this->activate]['no_auth']) == FALSE 138 | && empty($this->config[$this->activate]['password'])) 139 | { 140 | show_error("Password missing from mongodb config group : {$this->activate}", 500); 141 | } 142 | else 143 | { 144 | $this->password = trim($this->config[$this->activate]['password']); 145 | } 146 | 147 | if(empty($this->config[$this->activate]['database'])) 148 | { 149 | show_error("Database name missing from mongodb config group : {$this->activate}", 500); 150 | } 151 | else 152 | { 153 | $this->database = trim($this->config[$this->activate]['database']); 154 | } 155 | 156 | if(empty($this->config[$this->activate]['db_debug'])) 157 | { 158 | $this->debug = FALSE; 159 | } 160 | else 161 | { 162 | $this->debug = $this->config[$this->activate]['db_debug']; 163 | } 164 | 165 | if(empty($this->config[$this->activate]['return_as'])) 166 | { 167 | $this->return_as = 'array'; 168 | } 169 | else 170 | { 171 | $this->return_as = $this->config[$this->activate]['return_as']; 172 | } 173 | 174 | if(empty($this->config[$this->activate]['legacy_support'])) 175 | { 176 | $this->legacy_support = false; 177 | } 178 | else 179 | { 180 | $this->legacy_support = $this->config[$this->activate]['legacy_support']; 181 | } 182 | 183 | if(empty($this->config[$this->activate]['read_preference']) || 184 | !isset($this->config[$this->activate]['read_preference'])) 185 | { 186 | $this->read_preference = MongoDB\Driver\ReadPreference::RP_PRIMARY; 187 | } 188 | else 189 | { 190 | $this->read_preference = $this->config[$this->activate]['read_preference']; 191 | } 192 | 193 | if(empty($this->config[$this->activate]['read_concern']) || 194 | !isset($this->config[$this->activate]['read_concern'])) 195 | { 196 | $this->read_concern = MongoDB\Driver\ReadConcern::MAJORITY; 197 | } 198 | else 199 | { 200 | $this->read_concern = $this->config[$this->activate]['read_concern']; 201 | } 202 | 203 | 204 | } 205 | else 206 | { 207 | show_error("mongodb config group : {$this->activate} does not exist.", 500); 208 | } 209 | } 210 | 211 | /** 212 | * Sets the return as to object or array 213 | * This is useful if library is used in another library to avoid issue if config values are different 214 | * 215 | * @param string $value 216 | */ 217 | public function set_return_as($value) 218 | { 219 | if(!in_array($value, ['array', 'object'])) 220 | { 221 | show_error("Invalid Return As Type"); 222 | } 223 | $this->return_as = $value; 224 | } 225 | 226 | /** 227 | * -------------------------------------------------------------------------------- 228 | * Connect to MongoDB Database 229 | * -------------------------------------------------------------------------------- 230 | * 231 | * Connect to mongoDB database or throw exception with the error message. 232 | */ 233 | 234 | private function connect() 235 | { 236 | $this->prepare(); 237 | try 238 | { 239 | $dns = "mongodb://{$this->hostname}:{$this->port}/{$this->database}"; 240 | if(isset($this->config[$this->activate]['no_auth']) == TRUE && $this->config[$this->activate]['no_auth'] == TRUE) 241 | { 242 | $options = array(); 243 | } 244 | else 245 | { 246 | $options = array('username'=>$this->username, 'password'=>$this->password); 247 | } 248 | 249 | $this->connect = $this->db = new MongoDB\Driver\Manager($dns, $options); 250 | 251 | } 252 | catch (MongoDB\Driver\Exception\Exception $e) 253 | { 254 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 255 | { 256 | show_error("Unable to connect to MongoDB: {$e->getMessage()}", 500); 257 | } 258 | else 259 | { 260 | show_error("Unable to connect to MongoDB", 500); 261 | } 262 | } 263 | } 264 | 265 | /** 266 | * -------------------------------------------------------------------------------- 267 | * //! Insert 268 | * -------------------------------------------------------------------------------- 269 | * 270 | * Insert a new document into the passed collection 271 | * 272 | * @usage : $this->mongo_db->insert('foo', $data = array()); 273 | */ 274 | public function insert($collection = "", $insert = array()) 275 | { 276 | if (empty($collection)) 277 | { 278 | show_error("No Mongo collection selected to insert into", 500); 279 | } 280 | 281 | if (!is_array($insert) || count($insert) == 0) 282 | { 283 | show_error("Nothing to insert into Mongo collection or insert is not an array", 500); 284 | } 285 | 286 | if(isset($insert['_id']) === false) 287 | { 288 | $insert['_id'] = new MongoDB\BSON\ObjectId; 289 | } 290 | 291 | $bulk = new MongoDB\Driver\BulkWrite(); 292 | $bulk->insert($insert); 293 | 294 | $writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000); 295 | 296 | try 297 | { 298 | $write = $this->db->executeBulkWrite($this->database.".".$collection, $bulk, $writeConcern); 299 | return $this->convert_document_id($insert); 300 | } 301 | // Check if the write concern could not be fulfilled 302 | catch (MongoDB\Driver\Exception\BulkWriteException $e) 303 | { 304 | $result = $e->getWriteResult(); 305 | 306 | if ($writeConcernError = $result->getWriteConcernError()) 307 | { 308 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 309 | { 310 | show_error("WriteConcern failure : {$writeConcernError->getMessage()}", 500); 311 | } 312 | else 313 | { 314 | show_error("WriteConcern failure", 500); 315 | } 316 | } 317 | } 318 | // Check if any general error occured. 319 | catch (MongoDB\Driver\Exception\Exception $e) 320 | { 321 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 322 | { 323 | show_error("Insert of data into MongoDB failed: {$e->getMessage()}", 500); 324 | } 325 | else 326 | { 327 | show_error("Insert of data into MongoDB failed", 500); 328 | } 329 | } 330 | } 331 | 332 | /** 333 | * -------------------------------------------------------------------------------- 334 | * Batch Insert 335 | * -------------------------------------------------------------------------------- 336 | * 337 | * Insert a multiple document into the collection 338 | * 339 | * @usage : $this->mongo_db->batch_insert('foo', $data = array()); 340 | * @return : bool or array : if query fail then false else array of _id successfully inserted. 341 | */ 342 | public function batch_insert($collection = "", $insert = array()) 343 | { 344 | if (empty($collection)) 345 | { 346 | show_error("No Mongo collection selected to insert into", 500); 347 | } 348 | 349 | if (!is_array($insert) || count($insert) == 0) 350 | { 351 | show_error("Nothing to insert into Mongo collection or insert is not an array", 500); 352 | } 353 | 354 | $doc = new MongoDB\Driver\BulkWrite(); 355 | 356 | foreach ($insert as $ins) 357 | { 358 | if(isset($ins['_id']) === false) 359 | { 360 | $ins['_id'] = new MongoDB\BSON\ObjectId; 361 | } 362 | $doc->insert($ins); 363 | } 364 | 365 | $writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000); 366 | 367 | try 368 | { 369 | $result = $this->db->executeBulkWrite($this->database.".".$collection, $doc, $writeConcern); 370 | return $result; 371 | } 372 | // Check if the write concern could not be fulfilled 373 | catch (MongoDB\Driver\Exception\BulkWriteException $e) 374 | { 375 | $result = $e->getWriteResult(); 376 | 377 | if ($writeConcernError = $result->getWriteConcernError()) 378 | { 379 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 380 | { 381 | show_error("WriteConcern failure : {$writeConcernError->getMessage()}", 500); 382 | } 383 | else 384 | { 385 | show_error("WriteConcern failure", 500); 386 | } 387 | } 388 | } 389 | // Check if any general error occured. 390 | catch (MongoDB\Driver\Exception\Exception $e) 391 | { 392 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 393 | { 394 | show_error("Insert of data into MongoDB failed: {$e->getMessage()}", 500); 395 | } 396 | else 397 | { 398 | show_error("Insert of data into MongoDB failed", 500); 399 | } 400 | } 401 | } 402 | 403 | /** 404 | * -------------------------------------------------------------------------------- 405 | * //! Select 406 | * -------------------------------------------------------------------------------- 407 | * 408 | * Determine which fields to include OR which to exclude during the query process. 409 | * If you want to only choose fields to exclude, leave $includes an empty array(). 410 | * 411 | * @usage: $this->mongo_db->select(array('foo', 'bar'))->get('foobar'); 412 | */ 413 | public function select($includes = array(), $excludes = array()) 414 | { 415 | if ( ! is_array($includes)) 416 | { 417 | $includes = array(); 418 | } 419 | if ( ! is_array($excludes)) 420 | { 421 | $excludes = array(); 422 | } 423 | if ( ! empty($includes)) 424 | { 425 | foreach ($includes as $key=> $col) 426 | { 427 | if(is_array($col)){ 428 | //support $elemMatch in select 429 | $this->selects[$key] = $col; 430 | }else{ 431 | $this->selects[$col] = 1; 432 | } 433 | } 434 | } 435 | if ( ! empty($excludes)) 436 | { 437 | foreach ($excludes as $col) 438 | { 439 | $this->selects[$col] = 0; 440 | } 441 | } 442 | return ($this); 443 | } 444 | 445 | /** 446 | * -------------------------------------------------------------------------------- 447 | * //! Where 448 | * -------------------------------------------------------------------------------- 449 | * 450 | * Get the documents based on these search parameters. The $wheres array should 451 | * be an associative array with the field as the key and the value as the search 452 | * criteria. 453 | * 454 | * @usage : $this->mongo_db->where(array('foo' => 'bar'))->get('foobar'); 455 | */ 456 | public function where($wheres, $value = null) 457 | { 458 | if (is_array($wheres)) 459 | { 460 | foreach ($wheres as $wh => $val) 461 | { 462 | $this->wheres[$wh] = $val; 463 | } 464 | } 465 | else 466 | { 467 | $this->wheres[$wheres] = $value; 468 | } 469 | return $this; 470 | } 471 | 472 | /** 473 | * -------------------------------------------------------------------------------- 474 | * or where 475 | * -------------------------------------------------------------------------------- 476 | * 477 | * Get the documents where the value of a $field may be something else 478 | * 479 | * @usage : $this->mongo_db->where_or(array('foo'=>'bar', 'bar'=>'foo'))->get('foobar'); 480 | */ 481 | public function where_or($wheres = array()) 482 | { 483 | if (is_array($wheres) && count($wheres) > 0) 484 | { 485 | if ( ! isset($this->wheres['$or']) || ! is_array($this->wheres['$or'])) 486 | { 487 | $this->wheres['$or'] = array(); 488 | } 489 | foreach ($wheres as $wh => $val) 490 | { 491 | $this->wheres['$or'][] = array($wh=>$val); 492 | } 493 | return ($this); 494 | } 495 | else 496 | { 497 | show_error("Where value should be an array.", 500); 498 | } 499 | } 500 | 501 | /** 502 | * -------------------------------------------------------------------------------- 503 | * Where in 504 | * -------------------------------------------------------------------------------- 505 | * 506 | * Get the documents where the value of a $field is in a given $in array(). 507 | * 508 | * @usage : $this->mongo_db->where_in('foo', array('bar', 'zoo', 'blah'))->get('foobar'); 509 | */ 510 | public function where_in($field = "", $in = array()) 511 | { 512 | if (empty($field)) 513 | { 514 | show_error("Mongo field is require to perform where in query.", 500); 515 | } 516 | 517 | if (is_array($in) && count($in) > 0) 518 | { 519 | $this->_w($field); 520 | $this->wheres[$field]['$in'] = $in; 521 | return ($this); 522 | } 523 | else 524 | { 525 | show_error("in value should be an array.", 500); 526 | } 527 | } 528 | 529 | /** 530 | * -------------------------------------------------------------------------------- 531 | * Where in all 532 | * -------------------------------------------------------------------------------- 533 | * 534 | * Get the documents where the value of a $field is in all of a given $in array(). 535 | * 536 | * @usage : $this->mongo_db->where_in_all('foo', array('bar', 'zoo', 'blah'))->get('foobar'); 537 | */ 538 | public function where_in_all($field = "", $in = array()) 539 | { 540 | if (empty($field)) 541 | { 542 | show_error("Mongo field is require to perform where all in query.", 500); 543 | } 544 | 545 | if (is_array($in) && count($in) > 0) 546 | { 547 | $this->_w($field); 548 | $this->wheres[$field]['$all'] = $in; 549 | return ($this); 550 | } 551 | else 552 | { 553 | show_error("in value should be an array.", 500); 554 | } 555 | } 556 | 557 | /** 558 | * -------------------------------------------------------------------------------- 559 | * Where not in 560 | * -------------------------------------------------------------------------------- 561 | * 562 | * Get the documents where the value of a $field is not in a given $in array(). 563 | * 564 | * @usage : $this->mongo_db->where_not_in('foo', array('bar', 'zoo', 'blah'))->get('foobar'); 565 | */ 566 | public function where_not_in($field = "", $in = array()) 567 | { 568 | if (empty($field)) 569 | { 570 | show_error("Mongo field is require to perform where not in query.", 500); 571 | } 572 | 573 | if (is_array($in) && count($in) > 0) 574 | { 575 | $this->_w($field); 576 | $this->wheres[$field]['$nin'] = $in; 577 | return ($this); 578 | } 579 | else 580 | { 581 | show_error("in value should be an array.", 500); 582 | } 583 | } 584 | 585 | /** 586 | * -------------------------------------------------------------------------------- 587 | * Where greater than 588 | * -------------------------------------------------------------------------------- 589 | * 590 | * Get the documents where the value of a $field is greater than $x 591 | * 592 | * @usage : $this->mongo_db->where_gt('foo', 20); 593 | */ 594 | public function where_gt($field = "", $x) 595 | { 596 | if (!isset($field)) 597 | { 598 | show_error("Mongo field is require to perform greater then query.", 500); 599 | } 600 | 601 | if (!isset($x)) 602 | { 603 | show_error("Mongo field's value is require to perform greater then query.", 500); 604 | } 605 | 606 | $this->_w($field); 607 | $this->wheres[$field]['$gt'] = $x; 608 | return ($this); 609 | } 610 | 611 | /** 612 | * -------------------------------------------------------------------------------- 613 | * Where greater than or equal to 614 | * -------------------------------------------------------------------------------- 615 | * 616 | * Get the documents where the value of a $field is greater than or equal to $x 617 | * 618 | * @usage : $this->mongo_db->where_gte('foo', 20); 619 | */ 620 | public function where_gte($field = "", $x) 621 | { 622 | if (!isset($field)) 623 | { 624 | show_error("Mongo field is require to perform greater then or equal query.", 500); 625 | } 626 | 627 | if (!isset($x)) 628 | { 629 | show_error("Mongo field's value is require to perform greater then or equal query.", 500); 630 | } 631 | 632 | $this->_w($field); 633 | $this->wheres[$field]['$gte'] = $x; 634 | return($this); 635 | } 636 | 637 | /** 638 | * -------------------------------------------------------------------------------- 639 | * Where less than 640 | * -------------------------------------------------------------------------------- 641 | * 642 | * Get the documents where the value of a $field is less than $x 643 | * 644 | * @usage : $this->mongo_db->where_lt('foo', 20); 645 | */ 646 | public function where_lt($field = "", $x) 647 | { 648 | if (!isset($field)) 649 | { 650 | show_error("Mongo field is require to perform less then query.", 500); 651 | } 652 | 653 | if (!isset($x)) 654 | { 655 | show_error("Mongo field's value is require to perform less then query.", 500); 656 | } 657 | 658 | $this->_w($field); 659 | $this->wheres[$field]['$lt'] = $x; 660 | return($this); 661 | } 662 | 663 | /** 664 | * -------------------------------------------------------------------------------- 665 | * Where less than or equal to 666 | * -------------------------------------------------------------------------------- 667 | * 668 | * Get the documents where the value of a $field is less than or equal to $x 669 | * 670 | * @usage : $this->mongo_db->where_lte('foo', 20); 671 | */ 672 | public function where_lte($field = "", $x) 673 | { 674 | if (!isset($field)) 675 | { 676 | show_error("Mongo field is require to perform less then or equal to query.", 500); 677 | } 678 | 679 | if (!isset($x)) 680 | { 681 | show_error("Mongo field's value is require to perform less then or equal to query.", 500); 682 | } 683 | 684 | $this->_w($field); 685 | $this->wheres[$field]['$lte'] = $x; 686 | return ($this); 687 | } 688 | 689 | /** 690 | * -------------------------------------------------------------------------------- 691 | * Where between 692 | * -------------------------------------------------------------------------------- 693 | * 694 | * Get the documents where the value of a $field is between $x and $y 695 | * 696 | * @usage : $this->mongo_db->where_between('foo', 20, 30); 697 | */ 698 | public function where_between($field = "", $x, $y) 699 | { 700 | if (!isset($field)) 701 | { 702 | show_error("Mongo field is require to perform greater then or equal to query.", 500); 703 | } 704 | 705 | if (!isset($x)) 706 | { 707 | show_error("Mongo field's start value is require to perform greater then or equal to query.", 500); 708 | } 709 | 710 | if (!isset($y)) 711 | { 712 | show_error("Mongo field's end value is require to perform greater then or equal to query.", 500); 713 | } 714 | 715 | $this->_w($field); 716 | $this->wheres[$field]['$gte'] = $x; 717 | $this->wheres[$field]['$lte'] = $y; 718 | return ($this); 719 | } 720 | 721 | /** 722 | * -------------------------------------------------------------------------------- 723 | * Where between and but not equal to 724 | * -------------------------------------------------------------------------------- 725 | * 726 | * Get the documents where the value of a $field is between but not equal to $x and $y 727 | * 728 | * @usage : $this->mongo_db->where_between_ne('foo', 20, 30); 729 | */ 730 | public function where_between_ne($field = "", $x, $y) 731 | { 732 | if (!isset($field)) 733 | { 734 | show_error("Mongo field is require to perform between and but not equal to query.", 500); 735 | } 736 | 737 | if (!isset($x)) 738 | { 739 | show_error("Mongo field's start value is require to perform between and but not equal to query.", 500); 740 | } 741 | 742 | if (!isset($y)) 743 | { 744 | show_error("Mongo field's end value is require to perform between and but not equal to query.", 500); 745 | } 746 | 747 | $this->_w($field); 748 | $this->wheres[$field]['$gt'] = $x; 749 | $this->wheres[$field]['$lt'] = $y; 750 | return ($this); 751 | } 752 | 753 | /** 754 | * -------------------------------------------------------------------------------- 755 | * Where not equal 756 | * -------------------------------------------------------------------------------- 757 | * 758 | * Get the documents where the value of a $field is not equal to $x 759 | * 760 | * @usage : $this->mongo_db->where_ne('foo', 1)->get('foobar'); 761 | */ 762 | public function where_ne($field = '', $x) 763 | { 764 | if (!isset($field)) 765 | { 766 | show_error("Mongo field is require to perform Where not equal to query.", 500); 767 | } 768 | 769 | if (!isset($x)) 770 | { 771 | show_error("Mongo field's value is require to perform Where not equal to query.", 500); 772 | } 773 | 774 | $this->_w($field); 775 | $this->wheres[$field]['$ne'] = $x; 776 | return ($this); 777 | } 778 | 779 | /** 780 | * -------------------------------------------------------------------------------- 781 | * Like 782 | * -------------------------------------------------------------------------------- 783 | * 784 | * Get the documents where the (string) value of a $field is like a value. The defaults 785 | * allow for a case-insensitive search. 786 | * 787 | * @param $flags 788 | * Allows for the typical regular expression flags: 789 | * i = case insensitive 790 | * m = multiline 791 | * x = can contain comments 792 | * l = locale 793 | * s = dotall, "." matches everything, including newlines 794 | * u = match unicode 795 | * 796 | * @param $enable_start_wildcard 797 | * If set to anything other than TRUE, a starting line character "^" will be prepended 798 | * to the search value, representing only searching for a value at the start of 799 | * a new line. 800 | * 801 | * @param $enable_end_wildcard 802 | * If set to anything other than TRUE, an ending line character "$" will be appended 803 | * to the search value, representing only searching for a value at the end of 804 | * a line. 805 | * 806 | * @usage : $this->mongo_db->like('foo', 'bar', 'im', FALSE, TRUE); 807 | */ 808 | public function like($field = "", $value = "", $flags = "i", $enable_start_wildcard = TRUE, $enable_end_wildcard = TRUE) 809 | { 810 | if (empty($field)) 811 | { 812 | show_error("Mongo field is require to perform like query.", 500); 813 | } 814 | 815 | if (empty($value)) 816 | { 817 | show_error("Mongo field's value is require to like query.", 500); 818 | } 819 | 820 | $field = (string) trim($field); 821 | $this->_w($field); 822 | $value = (string) trim($value); 823 | $value = quotemeta($value); 824 | if ($enable_start_wildcard !== TRUE) 825 | { 826 | $value = "^" . $value; 827 | } 828 | if ($enable_end_wildcard !== TRUE) 829 | { 830 | $value .= "$"; 831 | } 832 | $regex = "/$value/$flags"; 833 | $this->wheres[$field] = new MongoDB\BSON\Regex($regex); 834 | return ($this); 835 | } 836 | 837 | /** 838 | * -------------------------------------------------------------------------------- 839 | * // Get 840 | * -------------------------------------------------------------------------------- 841 | * 842 | * Get the documents based upon the passed parameters 843 | * 844 | * @usage : $this->mongo_db->get('foo'); 845 | */ 846 | public function get($collection = "") 847 | { 848 | if (empty($collection)) 849 | { 850 | show_error("In order to retrieve documents from MongoDB, a collection name must be passed", 500); 851 | } 852 | 853 | try{ 854 | 855 | $read_concern = new MongoDB\Driver\ReadConcern($this->read_concern); 856 | $read_preference = new MongoDB\Driver\ReadPreference($this->read_preference); 857 | 858 | $options = array(); 859 | $options['projection'] = $this->selects; 860 | $options['sort'] = $this->sorts; 861 | $options['skip'] = (int) $this->offset; 862 | $options['limit'] = (int) $this->limit; 863 | $options['readConcern'] = $read_concern; 864 | 865 | $query = new MongoDB\Driver\Query($this->wheres, $options); 866 | $cursor = $this->db->executeQuery($this->database.".".$collection, $query, $read_preference); 867 | 868 | // Clear 869 | $this->_clear(); 870 | $returns = array(); 871 | 872 | if ($cursor instanceof MongoDB\Driver\Cursor) 873 | { 874 | $it = new \IteratorIterator($cursor); 875 | $it->rewind(); 876 | 877 | while ($doc = (array)$it->current()) 878 | { 879 | if ($this->return_as == 'object') 880 | { 881 | $returns[] = (object) $this->convert_document_id($doc); 882 | } 883 | else 884 | { 885 | $returns[] = (array) $this->convert_document_id($doc); 886 | } 887 | $it->next(); 888 | } 889 | } 890 | 891 | if ($this->return_as == 'object') 892 | { 893 | return (object)$returns; 894 | } 895 | else 896 | { 897 | return $returns; 898 | } 899 | } 900 | catch (MongoDB\Driver\Exception $e) 901 | { 902 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 903 | { 904 | show_error("MongoDB query failed: {$e->getMessage()}", 500); 905 | } 906 | else 907 | { 908 | show_error("MongoDB query failed.", 500); 909 | } 910 | } 911 | } 912 | 913 | /** 914 | * -------------------------------------------------------------------------------- 915 | * // Get where 916 | * -------------------------------------------------------------------------------- 917 | * 918 | * Get the documents based upon the passed parameters 919 | * 920 | * @usage : $this->mongo_db->get_where('foo', array('bar' => 'something')); 921 | */ 922 | public function get_where($collection = "", $where = array()) 923 | { 924 | if (is_array($where) && count($where) > 0) 925 | { 926 | return $this->where($where) 927 | ->get($collection); 928 | } 929 | else 930 | { 931 | show_error("Nothing passed to perform search or value is empty.", 500); 932 | } 933 | } 934 | 935 | /** 936 | * -------------------------------------------------------------------------------- 937 | * // Find One 938 | * -------------------------------------------------------------------------------- 939 | * 940 | * Get the single document based upon the passed parameters 941 | * 942 | * @usage : $this->mongo_db->find_one('foo'); 943 | */ 944 | public function find_one($collection = "") 945 | { 946 | 947 | if (empty($collection)) 948 | { 949 | show_error("In order to retrieve documents from MongoDB, a collection name must be passed", 500); 950 | } 951 | 952 | try{ 953 | 954 | $read_concern = new MongoDB\Driver\ReadConcern($this->read_concern); 955 | $read_preference = new MongoDB\Driver\ReadPreference($this->read_preference); 956 | 957 | $options = array(); 958 | $options['projection'] = $this->selects; 959 | $options['sort'] = $this->sorts; 960 | $options['skip'] = (int) $this->offset; 961 | $options['limit'] = (int) 1; 962 | $options['readConcern'] = $read_concern; 963 | 964 | $query = new MongoDB\Driver\Query($this->wheres, $options); 965 | $cursor = $this->db->executeQuery($this->database.".".$collection, $query, $read_preference); 966 | 967 | // Clear 968 | $this->_clear(); 969 | $returns = array(); 970 | 971 | if ($cursor instanceof MongoDB\Driver\Cursor) 972 | { 973 | $it = new \IteratorIterator($cursor); 974 | $it->rewind(); 975 | 976 | while ($doc = (array)$it->current()) 977 | { 978 | if ($this->return_as == 'object') 979 | { 980 | $returns[] = (object) $this->convert_document_id($doc); 981 | } 982 | else 983 | { 984 | $returns[] = (array) $this->convert_document_id($doc); 985 | } 986 | $it->next(); 987 | } 988 | } 989 | 990 | if ($this->return_as == 'object') 991 | { 992 | return (object)$returns; 993 | } 994 | else 995 | { 996 | return $returns; 997 | } 998 | } 999 | catch (MongoDB\Driver\Exception $e) 1000 | { 1001 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1002 | { 1003 | show_error("MongoDB query failed: {$e->getMessage()}", 500); 1004 | } 1005 | else 1006 | { 1007 | show_error("MongoDB query failed.", 500); 1008 | } 1009 | } 1010 | } 1011 | 1012 | /** 1013 | * -------------------------------------------------------------------------------- 1014 | * Count 1015 | * -------------------------------------------------------------------------------- 1016 | * 1017 | * Count the documents based upon the passed parameters 1018 | * 1019 | * @usage : $this->mongo_db->count('foo'); 1020 | */ 1021 | public function count($collection = "") 1022 | { 1023 | if (empty($collection)) 1024 | { 1025 | show_error("In order to retrieve documents from MongoDB, a collection name must be passed", 500); 1026 | } 1027 | 1028 | try{ 1029 | 1030 | $read_concern = new MongoDB\Driver\ReadConcern($this->read_concern); 1031 | $read_preference = new MongoDB\Driver\ReadPreference($this->read_preference); 1032 | 1033 | $options = array(); 1034 | $options['projection'] = array('_id'=>1); 1035 | $options['sort'] = $this->sorts; 1036 | $options['skip'] = (int) $this->offset; 1037 | $options['limit'] = (int) $this->limit; 1038 | $options['readConcern'] = $read_concern; 1039 | 1040 | $query = new MongoDB\Driver\Query($this->wheres, $options); 1041 | $cursor = $this->db->executeQuery($this->database.".".$collection, $query, $read_preference); 1042 | $array = $cursor->toArray(); 1043 | // Clear 1044 | $this->_clear(); 1045 | return count($array); 1046 | } 1047 | catch (MongoDB\Driver\Exception $e) 1048 | { 1049 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1050 | { 1051 | show_error("MongoDB query failed: {$e->getMessage()}", 500); 1052 | } 1053 | else 1054 | { 1055 | show_error("MongoDB query failed.", 500); 1056 | } 1057 | } 1058 | } 1059 | 1060 | /** 1061 | * -------------------------------------------------------------------------------- 1062 | * Count All Results 1063 | * -------------------------------------------------------------------------------- 1064 | * 1065 | * Alias to count method for compatibility with CI Query Builder 1066 | * 1067 | * @usage : $this->mongo_db->count('foo'); 1068 | */ 1069 | public function count_all_results($collection = "") 1070 | { 1071 | return $this->count($collection); 1072 | } 1073 | 1074 | /** 1075 | * -------------------------------------------------------------------------------- 1076 | * Set 1077 | * -------------------------------------------------------------------------------- 1078 | * 1079 | * Sets a field to a value 1080 | * 1081 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->set('posted', 1)->update('blog_posts'); 1082 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->set(array('posted' => 1, 'time' => time()))->update('blog_posts'); 1083 | */ 1084 | public function set($fields, $value = NULL) 1085 | { 1086 | $this->_u('$set'); 1087 | if (is_string($fields)) 1088 | { 1089 | $this->updates['$set'][$fields] = $value; 1090 | } 1091 | elseif (is_array($fields)) 1092 | { 1093 | foreach ($fields as $field => $value) 1094 | { 1095 | $this->updates['$set'][$field] = $value; 1096 | } 1097 | } 1098 | return $this; 1099 | } 1100 | 1101 | /** 1102 | * -------------------------------------------------------------------------------- 1103 | * Unset 1104 | * -------------------------------------------------------------------------------- 1105 | * 1106 | * Unsets a field (or fields) 1107 | * 1108 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->unset('posted')->update('blog_posts'); 1109 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->set(array('posted','time'))->update('blog_posts'); 1110 | */ 1111 | public function unset_field($fields) 1112 | { 1113 | $this->_u('$unset'); 1114 | if (is_string($fields)) 1115 | { 1116 | $this->updates['$unset'][$fields] = 1; 1117 | } 1118 | elseif (is_array($fields)) 1119 | { 1120 | foreach ($fields as $field) 1121 | { 1122 | $this->updates['$unset'][$field] = 1; 1123 | } 1124 | } 1125 | return $this; 1126 | } 1127 | 1128 | /** 1129 | * -------------------------------------------------------------------------------- 1130 | * Add to set 1131 | * -------------------------------------------------------------------------------- 1132 | * 1133 | * Adds value to the array only if its not in the array already 1134 | * 1135 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->addtoset('tags', 'php')->update('blog_posts'); 1136 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->addtoset('tags', array('php', 'codeigniter', 'mongodb'))->update('blog_posts'); 1137 | */ 1138 | public function addtoset($field, $values) 1139 | { 1140 | $this->_u('$addToSet'); 1141 | if (is_string($values)) 1142 | { 1143 | $this->updates['$addToSet'][$field] = $values; 1144 | } 1145 | elseif (is_array($values)) 1146 | { 1147 | $this->updates['$addToSet'][$field] = array('$each' => $values); 1148 | } 1149 | return $this; 1150 | } 1151 | 1152 | /** 1153 | * -------------------------------------------------------------------------------- 1154 | * Push 1155 | * -------------------------------------------------------------------------------- 1156 | * 1157 | * Pushes values into a field (field must be an array) 1158 | * 1159 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->push('comments', array('text'=>'Hello world'))->update('blog_posts'); 1160 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->push(array('comments' => array('text'=>'Hello world')), 'viewed_by' => array('Alex')->update('blog_posts'); 1161 | */ 1162 | public function push($fields, $value = array()) 1163 | { 1164 | $this->_u('$push'); 1165 | if (is_string($fields)) 1166 | { 1167 | $this->updates['$push'][$fields] = $value; 1168 | } 1169 | elseif (is_array($fields)) 1170 | { 1171 | foreach ($fields as $field => $value) 1172 | { 1173 | $this->updates['$push'][$field] = $value; 1174 | } 1175 | } 1176 | return $this; 1177 | } 1178 | 1179 | /** 1180 | * -------------------------------------------------------------------------------- 1181 | * Pop 1182 | * -------------------------------------------------------------------------------- 1183 | * 1184 | * Pops the last value from a field (field must be an array) 1185 | * 1186 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->pop('comments')->update('blog_posts'); 1187 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->pop(array('comments', 'viewed_by'))->update('blog_posts'); 1188 | */ 1189 | public function pop($field) 1190 | { 1191 | $this->_u('$pop'); 1192 | if (is_string($field)) 1193 | { 1194 | $this->updates['$pop'][$field] = -1; 1195 | } 1196 | elseif (is_array($field)) 1197 | { 1198 | foreach ($field as $pop_field) 1199 | { 1200 | $this->updates['$pop'][$pop_field] = -1; 1201 | } 1202 | } 1203 | return $this; 1204 | } 1205 | 1206 | /** 1207 | * -------------------------------------------------------------------------------- 1208 | * Pull 1209 | * -------------------------------------------------------------------------------- 1210 | * 1211 | * Removes by an array by the value of a field 1212 | * 1213 | * @usage: $this->mongo_db->pull('comments', array('comment_id'=>123))->update('blog_posts'); 1214 | */ 1215 | public function pull($field = "", $value = array()) 1216 | { 1217 | $this->_u('$pull'); 1218 | $this->updates['$pull'] = array($field => $value); 1219 | return $this; 1220 | } 1221 | 1222 | /** 1223 | * -------------------------------------------------------------------------------- 1224 | * Rename field 1225 | * -------------------------------------------------------------------------------- 1226 | * 1227 | * Renames a field 1228 | * 1229 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->rename_field('posted_by', 'author')->update('blog_posts'); 1230 | */ 1231 | public function rename_field($old, $new) 1232 | { 1233 | $this->_u('$rename'); 1234 | $this->updates['$rename'] = array($old => $new); 1235 | return $this; 1236 | } 1237 | 1238 | /** 1239 | * -------------------------------------------------------------------------------- 1240 | * Inc 1241 | * -------------------------------------------------------------------------------- 1242 | * 1243 | * Increments the value of a field 1244 | * 1245 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->inc(array('num_comments' => 1))->update('blog_posts'); 1246 | */ 1247 | public function inc($fields = array(), $value = 0) 1248 | { 1249 | $this->_u('$inc'); 1250 | if (is_string($fields)) 1251 | { 1252 | $this->updates['$inc'][$fields] = $value; 1253 | } 1254 | elseif (is_array($fields)) 1255 | { 1256 | foreach ($fields as $field => $value) 1257 | { 1258 | $this->updates['$inc'][$field] = $value; 1259 | } 1260 | } 1261 | return $this; 1262 | } 1263 | 1264 | /** 1265 | * -------------------------------------------------------------------------------- 1266 | * Multiple 1267 | * -------------------------------------------------------------------------------- 1268 | * 1269 | * Multiple the value of a field 1270 | * 1271 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->mul(array('num_comments' => 3))->update('blog_posts'); 1272 | */ 1273 | public function mul($fields = array(), $value = 0) 1274 | { 1275 | $this->_u('$mul'); 1276 | if (is_string($fields)) 1277 | { 1278 | $this->updates['$mul'][$fields] = $value; 1279 | } 1280 | elseif (is_array($fields)) 1281 | { 1282 | foreach ($fields as $field => $value) 1283 | { 1284 | $this->updates['$mul'][$field] = $value; 1285 | } 1286 | } 1287 | return $this; 1288 | } 1289 | 1290 | /** 1291 | * -------------------------------------------------------------------------------- 1292 | * Maximum 1293 | * -------------------------------------------------------------------------------- 1294 | * 1295 | * The $max operator updates the value of the field to a specified value if the specified value is greater than the current value of the field. 1296 | * 1297 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->max(array('num_comments' => 3))->update('blog_posts'); 1298 | */ 1299 | public function max($fields = array(), $value = 0) 1300 | { 1301 | $this->_u('$max'); 1302 | if (is_string($fields)) 1303 | { 1304 | $this->updates['$max'][$fields] = $value; 1305 | } 1306 | elseif (is_array($fields)) 1307 | { 1308 | foreach ($fields as $field => $value) 1309 | { 1310 | $this->updates['$max'][$field] = $value; 1311 | } 1312 | } 1313 | return $this; 1314 | } 1315 | 1316 | /** 1317 | * -------------------------------------------------------------------------------- 1318 | * Minimum 1319 | * -------------------------------------------------------------------------------- 1320 | * 1321 | * The $min updates the value of the field to a specified value if the specified value is less than the current value of the field. 1322 | * 1323 | * @usage: $this->mongo_db->where(array('blog_id'=>123))->min(array('num_comments' => 3))->update('blog_posts'); 1324 | */ 1325 | public function min($fields = array(), $value = 0) 1326 | { 1327 | $this->_u('$min'); 1328 | if (is_string($fields)) 1329 | { 1330 | $this->updates['$min'][$fields] = $value; 1331 | } 1332 | elseif (is_array($fields)) 1333 | { 1334 | foreach ($fields as $field => $value) 1335 | { 1336 | $this->updates['$min'][$field] = $value; 1337 | } 1338 | } 1339 | return $this; 1340 | } 1341 | 1342 | /** 1343 | * -------------------------------------------------------------------------------- 1344 | * //! distinct 1345 | * -------------------------------------------------------------------------------- 1346 | * 1347 | * Finds the distinct values for a specified field across a single collection 1348 | * 1349 | * @usage: $this->mongo_db->distinct('collection', 'field'); 1350 | */ 1351 | public function distinct($collection = "", $field="") 1352 | { 1353 | if (empty($collection)) 1354 | { 1355 | show_error("No Mongo collection selected for update", 500); 1356 | } 1357 | 1358 | if (empty($field)) 1359 | { 1360 | show_error("Need Collection field information for performing distinct query", 500); 1361 | } 1362 | 1363 | try 1364 | { 1365 | $documents = $this->db->{$collection}->distinct($field, $this->wheres); 1366 | $this->_clear(); 1367 | if ($this->return_as == 'object') 1368 | { 1369 | return (object)$documents; 1370 | } 1371 | else 1372 | { 1373 | return $documents; 1374 | } 1375 | } 1376 | catch (MongoCursorException $e) 1377 | { 1378 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1379 | { 1380 | show_error("MongoDB Distinct Query Failed: {$e->getMessage()}", 500); 1381 | } 1382 | else 1383 | { 1384 | show_error("MongoDB failed", 500); 1385 | } 1386 | } 1387 | } 1388 | 1389 | /** 1390 | * -------------------------------------------------------------------------------- 1391 | * //! Update 1392 | * -------------------------------------------------------------------------------- 1393 | * 1394 | * Updates a single document in Mongo 1395 | * 1396 | * @usage: $this->mongo_db->update('foo', $data = array()); 1397 | */ 1398 | public function update($collection = "", $options = array()) 1399 | { 1400 | if (empty($collection)) 1401 | { 1402 | show_error("No Mongo collection selected for update", 500); 1403 | } 1404 | 1405 | $bulk = new MongoDB\Driver\BulkWrite(); 1406 | $bulk->update($this->wheres, $this->updates, $options); 1407 | 1408 | $writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000); 1409 | 1410 | try 1411 | { 1412 | $write = $this->db->executeBulkWrite($this->database.".".$collection, $bulk, $writeConcern); 1413 | $this->_clear(); 1414 | return $write; 1415 | } 1416 | // Check if the write concern could not be fulfilled 1417 | catch (MongoDB\Driver\Exception\BulkWriteException $e) 1418 | { 1419 | $result = $e->getWriteResult(); 1420 | 1421 | if ($writeConcernError = $result->getWriteConcernError()) 1422 | { 1423 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1424 | { 1425 | show_error("WriteConcern failure : {$writeConcernError->getMessage()}", 500); 1426 | } 1427 | else 1428 | { 1429 | show_error("WriteConcern failure", 500); 1430 | } 1431 | } 1432 | } 1433 | // Check if any general error occured. 1434 | catch (MongoDB\Driver\Exception\Exception $e) 1435 | { 1436 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1437 | { 1438 | show_error("Update of data into MongoDB failed: {$e->getMessage()}", 500); 1439 | } 1440 | else 1441 | { 1442 | show_error("Update of data into MongoDB failed", 500); 1443 | } 1444 | } 1445 | } 1446 | 1447 | /** 1448 | * -------------------------------------------------------------------------------- 1449 | * Update all 1450 | * -------------------------------------------------------------------------------- 1451 | * 1452 | * Updates a collection of documents 1453 | * 1454 | * @usage: $this->mongo_db->update_all('foo', $data = array()); 1455 | */ 1456 | public function update_all($collection = "", $data = array(), $options = array()) 1457 | { 1458 | if (empty($collection)) 1459 | { 1460 | show_error("No Mongo collection selected to update", 500); 1461 | } 1462 | if (is_array($data) && count($data) > 0) 1463 | { 1464 | $this->updates = array_merge($data, $this->updates); 1465 | } 1466 | if (count($this->updates) == 0) 1467 | { 1468 | show_error("Nothing to update in Mongo collection or update is not an array", 500); 1469 | } 1470 | 1471 | $options = array_merge(array('multi' => TRUE), $options); 1472 | 1473 | $bulk = new MongoDB\Driver\BulkWrite(); 1474 | $bulk->update($this->wheres, $this->updates, $options); 1475 | 1476 | $writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000); 1477 | 1478 | try 1479 | { 1480 | $write = $this->db->executeBulkWrite($this->database.".".$collection, $bulk, $writeConcern); 1481 | $this->_clear(); 1482 | return $write; 1483 | } 1484 | // Check if the write concern could not be fulfilled 1485 | catch (MongoDB\Driver\Exception\BulkWriteException $e) 1486 | { 1487 | $result = $e->getWriteResult(); 1488 | 1489 | if ($writeConcernError = $result->getWriteConcernError()) 1490 | { 1491 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1492 | { 1493 | show_error("WriteConcern failure : {$writeConcernError->getMessage()}", 500); 1494 | } 1495 | else 1496 | { 1497 | show_error("WriteConcern failure", 500); 1498 | } 1499 | } 1500 | } 1501 | // Check if any general error occured. 1502 | catch (MongoDB\Driver\Exception\Exception $e) 1503 | { 1504 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1505 | { 1506 | show_error("Update of data into MongoDB failed: {$e->getMessage()}", 500); 1507 | } 1508 | else 1509 | { 1510 | show_error("Update of data into MongoDB failed", 500); 1511 | } 1512 | } 1513 | } 1514 | 1515 | /** 1516 | * -------------------------------------------------------------------------------- 1517 | * //! Delete 1518 | * -------------------------------------------------------------------------------- 1519 | * 1520 | * delete one document from the passed collection based upon certain criteria 1521 | * 1522 | * @usage : $this->mongo_db->where(array('field'=>'value'))->delete_all('foo'); 1523 | */ 1524 | public function delete($collection = "") 1525 | { 1526 | if (empty($collection)) 1527 | { 1528 | show_error("No Mongo collection selected for update", 500); 1529 | } 1530 | 1531 | $options = array('limit'=>true); 1532 | $bulk = new MongoDB\Driver\BulkWrite(); 1533 | $bulk->delete($this->wheres, $options); 1534 | 1535 | $writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000); 1536 | 1537 | try 1538 | { 1539 | $write = $this->db->executeBulkWrite($this->database.".".$collection, $bulk, $writeConcern); 1540 | $this->_clear(); 1541 | return $write; 1542 | } 1543 | // Check if the write concern could not be fulfilled 1544 | catch (MongoDB\Driver\Exception\BulkWriteException $e) 1545 | { 1546 | $result = $e->getWriteResult(); 1547 | 1548 | if ($writeConcernError = $result->getWriteConcernError()) 1549 | { 1550 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1551 | { 1552 | show_error("WriteConcern failure : {$writeConcernError->getMessage()}", 500); 1553 | } 1554 | else 1555 | { 1556 | show_error("WriteConcern failure", 500); 1557 | } 1558 | } 1559 | } 1560 | // Check if any general error occured. 1561 | catch (MongoDB\Driver\Exception\Exception $e) 1562 | { 1563 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1564 | { 1565 | show_error("Update of data into MongoDB failed: {$e->getMessage()}", 500); 1566 | } 1567 | else 1568 | { 1569 | show_error("Update of data into MongoDB failed", 500); 1570 | } 1571 | } 1572 | } 1573 | 1574 | /** 1575 | * -------------------------------------------------------------------------------- 1576 | * Delete all 1577 | * -------------------------------------------------------------------------------- 1578 | * 1579 | * Delete all documents from the passed collection based upon certain criteria 1580 | * 1581 | * @usage : $this->mongo_db->where(array('field'=>'value'))->delete_all('foo'); 1582 | */ 1583 | public function delete_all($collection = "") 1584 | { 1585 | if (empty($collection)) 1586 | { 1587 | show_error("No Mongo collection selected for delete", 500); 1588 | } 1589 | 1590 | $options = array('limit'=>false); 1591 | $bulk = new MongoDB\Driver\BulkWrite(); 1592 | $bulk->delete($this->wheres, $options); 1593 | 1594 | $writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000); 1595 | 1596 | try 1597 | { 1598 | $write = $this->db->executeBulkWrite($this->database.".".$collection, $bulk, $writeConcern); 1599 | $this->_clear(); 1600 | return $write; 1601 | } 1602 | // Check if the write concern could not be fulfilled 1603 | catch (MongoDB\Driver\Exception\BulkWriteException $e) 1604 | { 1605 | $result = $e->getWriteResult(); 1606 | 1607 | if ($writeConcernError = $result->getWriteConcernError()) 1608 | { 1609 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1610 | { 1611 | show_error("WriteConcern failure : {$writeConcernError->getMessage()}", 500); 1612 | } 1613 | else 1614 | { 1615 | show_error("WriteConcern failure", 500); 1616 | } 1617 | } 1618 | } 1619 | // Check if any general error occured. 1620 | catch (MongoDB\Driver\Exception\Exception $e) 1621 | { 1622 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1623 | { 1624 | show_error("Delete of data into MongoDB failed: {$e->getMessage()}", 500); 1625 | } 1626 | else 1627 | { 1628 | show_error("Delete of data into MongoDB failed", 500); 1629 | } 1630 | } 1631 | } 1632 | 1633 | /** 1634 | * -------------------------------------------------------------------------------- 1635 | * Aggregation Operation 1636 | * -------------------------------------------------------------------------------- 1637 | * 1638 | * Perform aggregation on mongodb collection 1639 | * 1640 | * @usage : $this->mongo_db->aggregate('foo', $ops = array()); 1641 | */ 1642 | public function aggregate($collection, $operation) 1643 | { 1644 | if (empty($collection)) 1645 | { 1646 | show_error("In order to retreive documents from MongoDB, a collection name must be passed", 500); 1647 | } 1648 | 1649 | if (empty($operation) && !is_array($operation)) 1650 | { 1651 | show_error("Operation must be an array to perform aggregate.", 500); 1652 | } 1653 | 1654 | $command = array('aggregate'=>$collection, 'pipeline'=>$operation); 1655 | return $this->command($command); 1656 | } 1657 | 1658 | /** 1659 | * -------------------------------------------------------------------------------- 1660 | * // Order by 1661 | * -------------------------------------------------------------------------------- 1662 | * 1663 | * Sort the documents based on the parameters passed. To set values to descending order, 1664 | * you must pass values of either -1, FALSE, 'desc', or 'DESC', else they will be 1665 | * set to 1 (ASC). 1666 | * 1667 | * @usage : $this->mongo_db->order_by(array('foo' => 'ASC'))->get('foobar'); 1668 | */ 1669 | public function order_by($fields = array()) 1670 | { 1671 | foreach ($fields as $col => $val) 1672 | { 1673 | if ($val == -1 || $val === FALSE || strtolower($val) == 'desc') 1674 | { 1675 | $this->sorts[$col] = -1; 1676 | } 1677 | else 1678 | { 1679 | $this->sorts[$col] = 1; 1680 | } 1681 | } 1682 | return ($this); 1683 | } 1684 | 1685 | /** 1686 | * -------------------------------------------------------------------------------- 1687 | * Mongo Date 1688 | * -------------------------------------------------------------------------------- 1689 | * 1690 | * Create new MongoDate object from current time or pass timestamp to create 1691 | * mongodate. 1692 | * 1693 | * @usage : $this->mongo_db->date($timestamp); 1694 | */ 1695 | public function date($stamp = FALSE) 1696 | { 1697 | if ( $stamp == FALSE ) 1698 | { 1699 | return new MongoDB\BSON\UTCDateTime(); 1700 | } 1701 | else 1702 | { 1703 | return new MongoDB\BSON\UTCDateTime($stamp); 1704 | } 1705 | 1706 | } 1707 | 1708 | /** 1709 | * -------------------------------------------------------------------------------- 1710 | * // Limit results 1711 | * -------------------------------------------------------------------------------- 1712 | * 1713 | * Limit the result set to $x number of documents 1714 | * 1715 | * @usage : $this->mongo_db->limit($x); 1716 | */ 1717 | public function limit($x = 99999) 1718 | { 1719 | if ($x !== NULL && is_numeric($x) && $x >= 1) 1720 | { 1721 | $this->limit = (int) $x; 1722 | } 1723 | return ($this); 1724 | } 1725 | 1726 | /** 1727 | * -------------------------------------------------------------------------------- 1728 | * // Offset 1729 | * -------------------------------------------------------------------------------- 1730 | * 1731 | * Offset the result set to skip $x number of documents 1732 | * 1733 | * @usage : $this->mongo_db->offset($x); 1734 | */ 1735 | public function offset($x = 0) 1736 | { 1737 | if ($x !== NULL && is_numeric($x) && $x >= 1) 1738 | { 1739 | $this->offset = (int) $x; 1740 | } 1741 | return ($this); 1742 | } 1743 | 1744 | /** 1745 | * Converts document ID and returns document back. 1746 | * 1747 | * @param stdClass $document [Document] 1748 | * @return stdClass 1749 | */ 1750 | private function convert_document_id($document) 1751 | { 1752 | if ($this->legacy_support === TRUE && isset($document['_id']) && $document['_id'] instanceof MongoDB\BSON\ObjectId) 1753 | { 1754 | $new_id = $document['_id']->__toString(); 1755 | unset($document['_id']); 1756 | $document['_id'] = new \stdClass(); 1757 | $document['_id']->{'$id'} = $new_id; 1758 | } 1759 | return $document; 1760 | } 1761 | 1762 | /** 1763 | * -------------------------------------------------------------------------------- 1764 | * // Command 1765 | * -------------------------------------------------------------------------------- 1766 | * 1767 | * Runs a MongoDB command 1768 | * 1769 | * @param string : Collection name, array $query The command query 1770 | * @usage : $this->mongo_db->command($collection, array('geoNear'=>'buildings', 'near'=>array(53.228482, -0.547847), 'num' => 10, 'nearSphere'=>true)); 1771 | * @access public 1772 | * @return object or array 1773 | */ 1774 | 1775 | public function command($command = array()) 1776 | { 1777 | try{ 1778 | $cursor = $this->db->executeCommand($this->database, new MongoDB\Driver\Command($command)); 1779 | // Clear 1780 | $this->_clear(); 1781 | $returns = array(); 1782 | 1783 | if ($cursor instanceof MongoDB\Driver\Cursor) 1784 | { 1785 | $it = new \IteratorIterator($cursor); 1786 | $it->rewind(); 1787 | 1788 | while ($doc = (array)$it->current()) 1789 | { 1790 | if ($this->return_as == 'object') 1791 | { 1792 | $returns[] = (object) $this->convert_document_id($doc); 1793 | } 1794 | else 1795 | { 1796 | $returns[] = (array) $this->convert_document_id($doc); 1797 | } 1798 | $it->next(); 1799 | } 1800 | } 1801 | 1802 | if ($this->return_as == 'object') 1803 | { 1804 | return (object)$returns; 1805 | } 1806 | else 1807 | { 1808 | return $returns; 1809 | } 1810 | } 1811 | catch (MongoDB\Driver\Exception $e) 1812 | { 1813 | if(isset($this->debug) == TRUE && $this->debug == TRUE) 1814 | { 1815 | show_error("MongoDB query failed: {$e->getMessage()}", 500); 1816 | } 1817 | else 1818 | { 1819 | show_error("MongoDB query failed.", 500); 1820 | } 1821 | } 1822 | } 1823 | 1824 | 1825 | /** 1826 | * -------------------------------------------------------------------------------- 1827 | * //! Add indexes 1828 | * -------------------------------------------------------------------------------- 1829 | * 1830 | * Ensure an index of the keys in a collection with optional parameters. To set values to descending order, 1831 | * you must pass values of either -1, FALSE, 'desc', or 'DESC', else they will be 1832 | * set to 1 (ASC). 1833 | * 1834 | * @usage : $this->mongo_db->add_index($collection, array('first_name' => 'ASC', 'last_name' => -1), array('unique' => TRUE)); 1835 | */ 1836 | public function add_index($collection = "", $keys = array(), $options = array()) 1837 | { 1838 | if (empty($collection)) 1839 | { 1840 | show_error("No Mongo collection specified to add index to", 500); 1841 | } 1842 | 1843 | if (empty($keys) || ! is_array($keys)) 1844 | { 1845 | show_error("Index could not be created to MongoDB Collection because no keys were specified", 500); 1846 | } 1847 | 1848 | foreach ($keys as $col => $val) 1849 | { 1850 | if($val == -1 || $val === FALSE || strtolower($val) == 'desc') 1851 | { 1852 | $keys[$col] = -1; 1853 | } 1854 | else 1855 | { 1856 | $keys[$col] = 1; 1857 | } 1858 | } 1859 | $command = array(); 1860 | $command['createIndexes'] = $collection; 1861 | $command['indexes'] = array($keys); 1862 | 1863 | return $this->command($command); 1864 | } 1865 | 1866 | /** 1867 | * -------------------------------------------------------------------------------- 1868 | * Remove index 1869 | * -------------------------------------------------------------------------------- 1870 | * 1871 | * Remove an index of the keys in a collection. To set values to descending order, 1872 | * you must pass values of either -1, FALSE, 'desc', or 'DESC', else they will be 1873 | * set to 1 (ASC). 1874 | * 1875 | * @usage : $this->mongo_db->remove_index($collection, 'index_1'); 1876 | */ 1877 | public function remove_index($collection = "", $name = "") 1878 | { 1879 | if (empty($collection)) 1880 | { 1881 | show_error("No Mongo collection specified to remove index from", 500); 1882 | } 1883 | 1884 | if (empty($name)) 1885 | { 1886 | show_error("Index could not be removed from MongoDB Collection because no index name were specified", 500); 1887 | } 1888 | 1889 | $command = array(); 1890 | $command['dropIndexes'] = $collection; 1891 | $command['index'] = $name; 1892 | 1893 | return $this->command($command); 1894 | } 1895 | 1896 | /** 1897 | * -------------------------------------------------------------------------------- 1898 | * List indexes 1899 | * -------------------------------------------------------------------------------- 1900 | * 1901 | * Lists all indexes in a collection. 1902 | * 1903 | * @usage : $this->mongo_db->list_indexes($collection); 1904 | */ 1905 | public function list_indexes($collection = "") 1906 | { 1907 | if (empty($collection)) 1908 | { 1909 | show_error("No Mongo collection specified to list all indexes from", 500); 1910 | } 1911 | $command = array(); 1912 | $command['listIndexes'] = $collection; 1913 | 1914 | return $this->command($command); 1915 | } 1916 | 1917 | /** 1918 | * -------------------------------------------------------------------------------- 1919 | * //! Switch database 1920 | * -------------------------------------------------------------------------------- 1921 | * 1922 | * Switch from default database to a different db 1923 | * 1924 | * $this->mongo_db->switch_db('foobar'); 1925 | */ 1926 | public function switch_db($database = '') 1927 | { 1928 | //@todo 1929 | } 1930 | 1931 | /** 1932 | * -------------------------------------------------------------------------------- 1933 | * //! Drop database 1934 | * -------------------------------------------------------------------------------- 1935 | * 1936 | * Drop a Mongo database 1937 | * @usage: $this->mongo_db->drop_db("foobar"); 1938 | */ 1939 | public function drop_db($database = '') 1940 | { 1941 | if (empty($database)) 1942 | { 1943 | show_error('Failed to drop MongoDB database because name is empty', 500); 1944 | } 1945 | 1946 | $command = array(); 1947 | $command['dropDatabase'] = 1; 1948 | 1949 | return $this->command($command); 1950 | } 1951 | 1952 | /** 1953 | * -------------------------------------------------------------------------------- 1954 | * //! Drop collection 1955 | * -------------------------------------------------------------------------------- 1956 | * 1957 | * Drop a Mongo collection 1958 | * @usage: $this->mongo_db->drop_collection('bar'); 1959 | */ 1960 | public function drop_collection($col = '') 1961 | { 1962 | if (empty($col)) 1963 | { 1964 | show_error('Failed to drop MongoDB collection because collection name is empty', 500); 1965 | } 1966 | 1967 | $command = array(); 1968 | $command['drop'] = $col; 1969 | 1970 | return $this->command($command); 1971 | } 1972 | 1973 | /** 1974 | * -------------------------------------------------------------------------------- 1975 | * _clear 1976 | * -------------------------------------------------------------------------------- 1977 | * 1978 | * Resets the class variables to default settings 1979 | */ 1980 | private function _clear() 1981 | { 1982 | $this->selects = array(); 1983 | $this->updates = array(); 1984 | $this->wheres = array(); 1985 | $this->limit = 999999; 1986 | $this->offset = 0; 1987 | $this->sorts = array(); 1988 | } 1989 | 1990 | /** 1991 | * -------------------------------------------------------------------------------- 1992 | * Where initializer 1993 | * -------------------------------------------------------------------------------- 1994 | * 1995 | * Prepares parameters for insertion in $wheres array(). 1996 | */ 1997 | private function _w($param) 1998 | { 1999 | if ( ! isset($this->wheres[$param])) 2000 | { 2001 | $this->wheres[ $param ] = array(); 2002 | } 2003 | } 2004 | 2005 | /** 2006 | * -------------------------------------------------------------------------------- 2007 | * Update initializer 2008 | * -------------------------------------------------------------------------------- 2009 | * 2010 | * Prepares parameters for insertion in $updates array(). 2011 | */ 2012 | private function _u($method) 2013 | { 2014 | if ( ! isset($this->updates[$method])) 2015 | { 2016 | $this->updates[ $method ] = array(); 2017 | } 2018 | } 2019 | 2020 | } 2021 | --------------------------------------------------------------------------------