README.md 22.4 KB
Newer Older
Jens Segers's avatar
Jens Segers committed
1
Laravel MongoDB
Jens Segers's avatar
Jens Segers committed
2
===============
Jens Segers's avatar
Jens Segers committed
3

Jens Segers's avatar
Jens Segers committed
4
[![Latest Stable Version](http://img.shields.io/github/release/jenssegers/laravel-mongodb.svg)](https://packagist.org/packages/jenssegers/mongodb) [![Total Downloads](http://img.shields.io/packagist/dm/jenssegers/mongodb.svg)](https://packagist.org/packages/jenssegers/mongodb) [![Build Status](http://img.shields.io/travis/jenssegers/laravel-mongodb.svg)](https://travis-ci.org/jenssegers/laravel-mongodb) [![Coverage Status](http://img.shields.io/coveralls/jenssegers/laravel-mongodb.svg)](https://coveralls.io/r/jenssegers/laravel-mongodb?branch=master)
Jens Segers's avatar
Jens Segers committed
5

Jens Segers's avatar
Jens Segers committed
6
An Eloquent model and Query builder with support for MongoDB, using the original Laravel API. *This library extends the original Laravel classes, so it uses exactly the same methods.*
Jens Segers's avatar
Jens Segers committed
7

Jens Segers's avatar
Jens Segers committed
8
### Upgrading from v1 to v2
Jens Segers's avatar
Jens Segers committed
9

Jens Segers's avatar
Jens Segers committed
10
In this new version, embedded documents are no longer saved to the parent model using an attribute with a leading underscore. If you have a relation like `embedsMany('Book')`, these books are now stored under `$model['books']` instead of `$model['_books']`. This was changed to make embedded relations less confusing for new developers.
Jens Segers's avatar
Jens Segers committed
11

Jens Segers's avatar
Jens Segers committed
12
If you want to upgrade to this new version without having to change all your existing database objects, you can modify your embedded relations to use a non-default local key including the underscore:
Jens Segers's avatar
Jens Segers committed
13 14 15

    $this->embedsMany('Book', '_books');

Jens Segers's avatar
Jens Segers committed
16
Read the full changelog at https://github.com/jenssegers/laravel-mongodb/releases/tag/v2.0.0
17

18 19 20
Installation
------------

21 22
Make sure you have the MongoDB PHP driver installed. You can find installation instructions at http://php.net/manual/en/mongo.installation.php

23
Install using composer:
24

25
    composer require jenssegers/mongodb
26

Jens Segers's avatar
Jens Segers committed
27
Add the service provider in `app/config/app.php`:
28

Jens Segers's avatar
Jens Segers committed
29
    'Jenssegers\Mongodb\MongodbServiceProvider',
Jens Segers's avatar
Jens Segers committed
30

Jens Segers's avatar
Jens Segers committed
31
The service provider will register a mongodb database extension with the original database manager. There is no need to register additional facades or objects. When using mongodb connections, Laravel will automatically provide you with the corresponding mongodb objects.
Jens Segers's avatar
Jens Segers committed
32 33 34 35

Configuration
-------------

36 37 38 39 40
Change your default database connection name in `app/config/database.php`:

    'default' => 'mongodb',

And add a new mongodb connection:
Jens Segers's avatar
Jens Segers committed
41

Jens Segers's avatar
Jens Segers committed
42
    'mongodb' => array(
43
        'driver'   => 'mongodb',
Jens Segers's avatar
Jens Segers committed
44 45
        'host'     => 'localhost',
        'port'     => 27017,
46 47 48
        'username' => 'username',
        'password' => 'password',
        'database' => 'database'
Jens Segers's avatar
Jens Segers committed
49
    ),
Jens Segers's avatar
Jens Segers committed
50

51 52 53
You can connect to multiple servers or replica sets with the following configuration:

    'mongodb' => array(
54
        'driver'   => 'mongodb',
55
        'host'     => array('server1', 'server2'),
56 57 58 59 60 61 62
        'port'     => 27017,
        'username' => 'username',
        'password' => 'password',
        'database' => 'database',
        'options'  => array('replicaSet' => 'replicaSetName')
    ),

63
Eloquent
64 65
--------

66
This package includes a MongoDB enabled Eloquent class that you can use to define models for corresponding collections.
Jens Segers's avatar
Jens Segers committed
67

Jens Segers's avatar
Jens Segers committed
68
    use Jenssegers\Mongodb\Model as Eloquent;
Jens Segers's avatar
Jens Segers committed
69

70 71 72 73 74
    class User extends Eloquent {}

Note that we did not tell Eloquent which collection to use for the `User` model. Just like the original Eloquent, the lower-case, plural name of the class will be used as the table name unless another name is explicitly specified. You may specify a custom collection (alias for table) by defining a `collection` property on your model:

    use Jenssegers\Mongodb\Model as Eloquent;
Jens Segers's avatar
Jens Segers committed
75

76 77 78
    class User extends Eloquent {

        protected $collection = 'users_collection';
Jens Segers's avatar
Jens Segers committed
79

80 81
    }

82
**NOTE:** Eloquent will also assume that each collection has a primary key column named id. You may define a `primaryKey` property to override this convention. Likewise, you may define a `connection` property to override the name of the database connection that should be used when utilizing the model.
Jens Segers's avatar
Jens Segers committed
83 84 85 86 87 88 89 90

    use Jenssegers\Mongodb\Model as Eloquent;

    class MyModel extends Eloquent {

        protected $connection = 'mongodb';

    }
91

Jens Segers's avatar
Jens Segers committed
92
Everything else works just like the original Eloquent model. Read more about the Eloquent on http://laravel.com/docs/eloquent
93

Jens Segers's avatar
Jens Segers committed
94 95 96 97 98 99
### Optional: Alias

You may also register an alias for the MongoDB model by adding the following to the alias array in `app/config/app.php`:

    'Moloquent'       => 'Jenssegers\Mongodb\Model',

100
This will allow you to use the registered alias like:
wikichua's avatar
wikichua committed
101

102
    class MyModel extends Moloquent {}
wikichua's avatar
wikichua committed
103

104 105 106
Query Builder
-------------

Jens Segers's avatar
Jens Segers committed
107
The database driver plugs right into the original query builder. When using mongodb connections, you will be able to build fluent queries to perform database operations. For your convenience, there is a `collection` alias for `table` as well as some additional mongodb specific operators/operations.
Jens Segers's avatar
Jens Segers committed
108

109
    $users = DB::collection('users')->get();
110

111
    $user = DB::collection('users')->where('name', 'John')->first();
112

Jens Segers's avatar
Jens Segers committed
113
If you did not change your default database connection, you will need to specify it when querying.
Jens Segers's avatar
Jens Segers committed
114 115 116

    $user = DB::connection('mongodb')->collection('users')->get();

Jens Segers's avatar
Jens Segers committed
117 118
Read more about the query builder on http://laravel.com/docs/queries

119 120 121 122 123
Schema
------

The database driver also has (limited) schema builder support. You can easily manipulate collections and set indexes:

Jens Segers's avatar
Jens Segers committed
124
    Schema::create('users', function($collection)
125 126
    {
        $collection->index('name');
127

128 129 130 131 132
        $collection->unique('email');
    });

Supported operations are:

Jens Segers's avatar
Jens Segers committed
133 134 135
 - create and drop
 - collection
 - hasCollection
136
 - index and dropIndex (compound indexes supported as well)
137 138
 - unique
 - background, sparse, expire (MongoDB specific)
139

Jens Segers's avatar
Jens Segers committed
140
All other (unsupported) operations are implemented as dummy pass-through methods, because MongoDB does not use a predefined schema. Read more about the schema builder on http://laravel.com/docs/schema
141 142 143

Extensions
----------
144

145
### Auth
146 147 148 149 150 151 152

If you want to use Laravel's native Auth functionality, register this included service provider:

    'Jenssegers\Mongodb\Auth\ReminderServiceProvider',

This service provider will slightly modify the internal DatabaseReminderRepository to add support for MongoDB based password reminders. If you don't use password reminders, you don't have to register this service provider and everything else should work just fine.

153
### Sentry
154 155 156

If yo want to use this library with [Sentry](https://cartalyst.com/manual/sentry), then check out https://github.com/jenssegers/Laravel-MongoDB-Sentry

157
### Sessions
Jens Segers's avatar
Jens Segers committed
158

159
The MongoDB session driver is available in a separate package, check out https://github.com/jenssegers/Laravel-MongoDB-Session
Jens Segers's avatar
Jens Segers committed
160

161 162 163
Troubleshooting
---------------

164
#### Class 'MongoClient' not found in ...
165 166 167 168 169 170 171 172

The `MongoClient` class is part of the MongoDB PHP driver. Usually, this error means that you forgot to install, or did not install this driver correctly. You can find installation instructions for this driver at http://php.net/manual/en/mongo.installation.php.

To check if you have installed the driver correctly, run the following command:

    $ php -i | grep 'Mongo'
    MongoDB Support => enabled

173
#### Argument 2 passed to Illuminate\Database\Query\Builder::__construct() must be an instance of Illuminate\Database\Query\Grammars\Grammar, null given
174 175 176 177 178 179 180 181 182 183 184

To solve this, you will need to check two things. First check if your model is extending the correct class; this class should be `Jenssegers\Mongodb\Model`. Secondly, check if your model is using a MongoDB connection. If you did not change the default database connection in your database configuration file, you need to specify the MongoDB enabled connection. This is what your class should look like if you did not set up an alias and change the default database connection:

    use Jenssegers\Mongodb\Model as Eloquent;

    class User extends Eloquent {

        protected $connection = 'mongodb';

    }

Jens Segers's avatar
Jens Segers committed
185 186
Examples
--------
187

Jens Segers's avatar
Jens Segers committed
188 189
### Basic Usage

190 191
**Retrieving All Models**

Jens Segers's avatar
Jens Segers committed
192
    $users = User::all();
193 194 195

**Retrieving A Record By Primary Key**

Jens Segers's avatar
Jens Segers committed
196
    $user = User::find('517c43667db388101e00000f');
197 198 199

**Wheres**

Jens Segers's avatar
Jens Segers committed
200
    $users = User::where('votes', '>', 100)->take(10)->get();
201 202 203

**Or Statements**

Jens Segers's avatar
Jens Segers committed
204
    $users = User::where('votes', '>', 100)->orWhere('name', 'John')->get();
205

206 207 208
**And Statements**

    $users = User::where('votes', '>', 100)->where('name', '=', 'John')->get();
Jens Segers's avatar
Jens Segers committed
209

210 211
**Using Where In With An Array**

Jens Segers's avatar
Jens Segers committed
212
    $users = User::whereIn('age', array(16, 18, 20))->get();
Jens Segers's avatar
Jens Segers committed
213

Jens Segers's avatar
Jens Segers committed
214
When using `whereNotIn` objects will be returned if the field is non existent. Combine with `whereNotNull('age')` to leave out those documents.
215

Jens Segers's avatar
Jens Segers committed
216 217
**Using Where Between**

Jens Segers's avatar
Jens Segers committed
218
    $users = User::whereBetween('votes', array(1, 100))->get();
Jens Segers's avatar
Jens Segers committed
219

Jens Segers's avatar
Jens Segers committed
220 221
**Where null**

Jens Segers's avatar
Jens Segers committed
222
    $users = User::whereNull('updated_at')->get();
223 224 225

**Order By**

Jens Segers's avatar
Jens Segers committed
226
    $users = User::orderBy('name', 'desc')->get();
227

Jens Segers's avatar
Jens Segers committed
228 229
**Offset & Limit**

Jens Segers's avatar
Jens Segers committed
230
    $users = User::skip(10)->take(5)->get();
Jens Segers's avatar
Jens Segers committed
231

Jens Segers's avatar
Jens Segers committed
232 233 234 235
**Distinct**

Distinct requires a field for which to return the distinct values.

Jens Segers's avatar
Jens Segers committed
236 237 238
    $users = User::distinct()->get(array('name'));
    // or
    $users = User::distinct('name')->get();
Jens Segers's avatar
Jens Segers committed
239

Jens Segers's avatar
Jens Segers committed
240 241
Distinct can be combined with **where**:

Jens Segers's avatar
Jens Segers committed
242
    $users = User::where('active', true)->distinct('name')->get();
Jens Segers's avatar
Jens Segers committed
243

244 245
**Advanced Wheres**

Jens Segers's avatar
Jens Segers committed
246
    $users = User::where('name', '=', 'John')->orWhere(function($query)
Jens Segers's avatar
Jens Segers committed
247 248 249 250 251
        {
            $query->where('votes', '>', 100)
                  ->where('title', '<>', 'Admin');
        })
        ->get();
252

Jens Segers's avatar
Jens Segers committed
253 254
**Group By**

Jens Segers's avatar
Jens Segers committed
255 256
Selected columns that are not grouped will be aggregated with the $last function.

Jens Segers's avatar
Jens Segers committed
257
    $users = Users::groupBy('title')->get(array('title', 'name'));
Jens Segers's avatar
Jens Segers committed
258 259

**Aggregation**
Jens Segers's avatar
Jens Segers committed
260

261 262
*Aggregations are only available for MongoDB versions greater than 2.2.*

Jens Segers's avatar
Jens Segers committed
263 264 265 266 267
    $total = Order::count();
    $price = Order::max('price');
    $price = Order::min('price');
    $price = Order::avg('price');
    $total = Order::sum('price');
Jens Segers's avatar
Jens Segers committed
268 269 270

Aggregations can be combined with **where**:

Jens Segers's avatar
Jens Segers committed
271
    $sold = Orders::where('sold', true)->sum('price');
Jens Segers's avatar
Jens Segers committed
272 273 274

**Like**

Jens Segers's avatar
Jens Segers committed
275
    $user = Comment::where('body', 'like', '%spam%')->get();
Jens Segers's avatar
Jens Segers committed
276

277
**Incrementing or decrementing a value of a column**
278

279
Perform increments or decrements (default 1) on specified attributes:
280

Jens Segers's avatar
Jens Segers committed
281 282
    User::where('name', 'John Doe')->increment('age');
    User::where('name', 'Jaques')->decrement('weight', 50);
283

284
The number of updated objects is returned:
285

Jens Segers's avatar
Jens Segers committed
286
    $count = User->increment('age');
287

288
You may also specify additional columns to update:
289

Jens Segers's avatar
Jens Segers committed
290 291
    User::where('age', '29')->increment('age', 1, array('group' => 'thirty something'));
    User::where('bmi', 30)->decrement('bmi', 1, array('category' => 'overweight'));
Jens Segers's avatar
Jens Segers committed
292

293 294 295 296
**Soft deleting**

When soft deleting a model, it is not actually removed from your database. Instead, a deleted_at timestamp is set on the record. To enable soft deletes for a model, apply the SoftDeletingTrait to the model:

Jens Segers's avatar
Jens Segers committed
297
    use Jenssegers\Mongodb\Eloquent\SoftDeletingTrait;
298

Jens Segers's avatar
Jens Segers committed
299
    class User extends Eloquent {
300

Jens Segers's avatar
Jens Segers committed
301
        use SoftDeletingTrait;
302

Jens Segers's avatar
Jens Segers committed
303
        protected $dates = ['deleted_at'];
304

Jens Segers's avatar
Jens Segers committed
305
    }
306 307 308

For more information check http://laravel.com/docs/eloquent#soft-deleting

309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
### MongoDB specific operators

**Exists**

Matches documents that have the specified field.

    User::where('age', 'exists', true)->get();

**All**

Matches arrays that contain all elements specified in the query.

    User::where('roles', 'all', array('moderator', 'author'))->get();

**Size**

Selects documents if the array field is a specified size.

    User::where('tags', 'size', 3)->get();

Jens Segers's avatar
Jens Segers committed
329 330 331 332 333 334
**Regex**

Selects documents where values match a specified regular expression.

    User::where('name', 'regex', new MongoRegex("/.*doe/i"))->get();

Jens Segers's avatar
Jens Segers committed
335 336 337 338 339 340 341 342
**NOTE:** you can also use the Laravel regexp operations. These are a bit more flexible and will automatically convert your regular expression string to a MongoRegex object.

    User::where('name', 'regexp', '/.*doe/i'))->get();

And the inverse:

    User::where('name', 'not regexp', '/.*doe/i'))->get();

343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
**Type**

Selects documents if a field is of the specified type. For more information check: http://docs.mongodb.org/manual/reference/operator/query/type/#op._S_type

    User::where('age', 'type', 2)->get();

**Mod**

Performs a modulo operation on the value of a field and selects documents with a specified result.

    User::where('age', 'mod', array(10, 0))->get();

**Where**

Matches documents that satisfy a JavaScript expression. For more information check http://docs.mongodb.org/manual/reference/operator/query/where/#op._S_where

Jens Segers's avatar
Jens Segers committed
359 360
### Inserts, updates and deletes

361 362 363 364 365 366 367 368 369 370 371 372 373 374
Inserting, updating and deleting records works just like the original Eloquent.

**Saving a new model**

    $user = new User;
    $user->name = 'John';
    $user->save();

You may also use the create method to save a new model in a single line:

    User::create(array('name' => 'John'));

**Updating a model**

Mohit Mamoria's avatar
Mohit Mamoria committed
375
To update a model, you may retrieve it, change an attribute, and use the save method.
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394

    $user = User::first();
    $user->email = 'john@foo.com';
    $user->save();

*There is also support for upsert operations, check https://github.com/jenssegers/laravel-mongodb#mongodb-specific-operations*

**Deleting a model**

To delete a model, simply call the delete method on the instance:

    $user = User::first();
    $user->delete();

Or deleting a model by its key:

    User::destroy('517c43667db388101e00000f');

For more information about model manipulation, check http://laravel.com/docs/eloquent#insert-update-delete
Jens Segers's avatar
Jens Segers committed
395

396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
### Dates

Eloquent allows you to work with Carbon/DateTime objects instead of MongoDate objects. Internally, these dates will be converted to MongoDate objects when saved to the database. If you wish to use this functionality on non-default date fields you will need to manually specify them as described here: http://laravel.com/docs/eloquent#date-mutators

Example:

    use Jenssegers\Mongodb\Model as Eloquent;

    class User extends Eloquent {

        protected $dates = array('birthday');

    }

Which allows you to execute queries like:

    $users = User::where('birthday', '>', new DateTime('-18 years'))->get();

Jens Segers's avatar
Jens Segers committed
414
### Relations
Jens Segers's avatar
Jens Segers committed
415

Jens Segers's avatar
Jens Segers committed
416
Supported relations are:
Jens Segers's avatar
Jens Segers committed
417 418 419 420

 - hasOne
 - hasMany
 - belongsTo
421 422
 - belongsToMany

Jens Segers's avatar
Jens Segers committed
423 424
Example:

Jens Segers's avatar
Jens Segers committed
425 426
    use Jenssegers\Mongodb\Model as Eloquent;

Jens Segers's avatar
Jens Segers committed
427 428 429 430 431 432 433 434 435 436 437
    class User extends Eloquent {

        public function items()
        {
            return $this->hasMany('Item');
        }

    }

And the inverse relation:

Jens Segers's avatar
Jens Segers committed
438 439
    use Jenssegers\Mongodb\Model as Eloquent;

Jens Segers's avatar
Jens Segers committed
440 441 442 443 444 445 446 447 448
    class Item extends Eloquent {

        public function user()
        {
            return $this->belongsTo('User');
        }

    }

Jens Segers's avatar
Jens Segers committed
449 450 451 452 453 454 455 456 457 458 459 460 461
The belongsToMany relation will not use a pivot "table", but will push id's to a __related_ids__ attribute instead. This makes the second parameter for the belongsToMany method useless. If you want to define custom keys for your relation, set it to `null`:

    use Jenssegers\Mongodb\Model as Eloquent;

    class User extends Eloquent {

        public function groups()
        {
            return $this->belongsToMany('Group', null, 'users', 'groups');
        }

    }

Shubhamoy's avatar
Shubhamoy committed
462
Other relations are not yet supported, but may be added in the future. Read more about these relations on http://laravel.com/docs/eloquent#relationships
Jens Segers's avatar
Jens Segers committed
463

464 465
### EmbedsMany Relations

Jens Segers's avatar
Jens Segers committed
466
If you want to embed models, rather than referencing them, you can use the `embedsMany` relation. This relation is similar to the `hasMany` relation, but embeds the models inside the parent object.
467 468 469 470 471 472 473 474 475 476 477 478

    use Jenssegers\Mongodb\Model as Eloquent;

    class User extends Eloquent {

        public function books()
        {
            return $this->embedsMany('Book');
        }

    }

Jens Segers's avatar
Jens Segers committed
479
You access the embedded models through the dynamic property:
480 481 482

    $books = User::first()->books;

Jens Segers's avatar
Jens Segers committed
483
The inverse relation is auto*magically* available, you don't need to define this reverse relation.
Jens Segers's avatar
Jens Segers committed
484 485 486

    $user = $book->user;

Jens Segers's avatar
Jens Segers committed
487
Inserting and updating embedded models works similar to the `hasMany` relation:
488 489 490 491 492 493

    $book = new Book(array('title' => 'A Game of Thrones'));

    $user = User::first();

    $book = $user->books()->save($book);
Jens Segers's avatar
Jens Segers committed
494 495
    // or
    $book = $user->books()->create(array('title' => 'A Game of Thrones'))
496

Jens Segers's avatar
Jens Segers committed
497
You can update embedded models using their `save` method (available since release 2.0.0):
498 499 500

    $book = $user->books()->first();

Jens Segers's avatar
Jens Segers committed
501 502 503 504
    $book->title = 'A Game of Thrones';

    $book->save();

Jens Segers's avatar
Jens Segers committed
505
You can remove an embedded model by using the `destroy` method on the relation, or the `delete` method on the model (available since release 2.0.0):
Jens Segers's avatar
Jens Segers committed
506 507 508 509

    $book = $user->books()->first();

    $book->delete();
Jens Segers's avatar
Jens Segers committed
510 511
    // or
    $user->books()->destroy($book);
512

Jens Segers's avatar
Jens Segers committed
513
If you want to add or remove an embedded model, without touching the database, you can use the `associate` and `dissociate` methods. To eventually write the changes to the database, save the parent object:
514 515

    $user->books()->associate($book);
Jens Segers's avatar
Jens Segers committed
516

517 518
    $user->save();

Jens Segers's avatar
Jens Segers committed
519
Like other relations, embedsMany assumes the local key of the relationship based on the model name. You can override the default local key by passing a second argument to the embedsMany method:
520 521 522

    return $this->embedsMany('Book', 'local_key');

Jens Segers's avatar
Jens Segers committed
523
Embedded relations will return a Collection of embedded items instead of a query builder. To allow a more query-like behavior, a modified version of the Collection class is used, with support for the following **additional** operations:
Jens Segers's avatar
Jens Segers committed
524 525

 - where($key, $operator, $value)
526 527 528
 - whereIn($key, $values) and whereNotIn($key, $values)
 - whereBetween($key, $values) and whereNotBetween($key, $values)
 - whereNull($key) and whereNotNull($key)
Jens Segers's avatar
Jens Segers committed
529
 - orderBy($key, $direction)
530 531 532 533
 - oldest() and latest()
 - limit($value)
 - offset($value)
 - skip($value)
Jens Segers's avatar
Jens Segers committed
534 535

This allows you to execute simple queries on the collection results:
Jens Segers's avatar
Jens Segers committed
536 537 538

    $books = $user->books()->where('rating', '>', 5)->orderBy('title')->get();

Jens Segers's avatar
Jens Segers committed
539 540
**Note:** Because embedded models are not stored in a separate collection, you can not query all of embedded models. You will always have to access them through the parent model.

541 542
### EmbedsOne Relations

Jens Segers's avatar
Jens Segers committed
543
The embedsOne relation is similar to the EmbedsMany relation, but only embeds a single model.
544 545 546 547 548 549 550 551 552 553 554 555

    use Jenssegers\Mongodb\Model as Eloquent;

    class Book extends Eloquent {

        public function author()
        {
            return $this->embedsOne('Author');
        }

    }

Jens Segers's avatar
Jens Segers committed
556
You access the embedded models through the dynamic property:
557 558 559

    $author = Book::first()->author;

Jens Segers's avatar
Jens Segers committed
560
Inserting and updating embedded models works similar to the `hasOne` relation:
561 562 563 564 565

    $author = new Author(array('name' => 'John Doe'));

    $book = Books::first();

Jens Segers's avatar
Jens Segers committed
566 567 568 569
    $author = $book->author()->save($author);
    // or
    $author = $book->author()->create(array('name' => 'John Doe'));

Jens Segers's avatar
Jens Segers committed
570
You can update the embedded model using the `save` method (available since release 2.0.0):
Jens Segers's avatar
Jens Segers committed
571 572 573 574 575 576

    $author = $book->author;

    $author->name = 'Jane Doe';
    $author->save();

Jens Segers's avatar
Jens Segers committed
577
You can replace the embedded model with a new model like this:
Jens Segers's avatar
Jens Segers committed
578 579 580

    $newAuthor = new Author(array('name' => 'Jane Doe'));
    $book->author()->save($newAuthor);
581

582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
### MySQL Relations

If you're using a hybrid MongoDB and SQL setup, you're in luck! The model will automatically return a MongoDB- or SQL-relation based on the type of the related model. Of course, if you want this functionality to work both ways, your SQL-models will need to extend `Jenssegers\Eloquent\Model`. Note that this functionality only works for hasOne, hasMany and belongsTo relations.

Example SQL-based User model:

    use Jenssegers\Eloquent\Model as Eloquent;

    class User extends Eloquent {

        protected $connection = 'mysql';

        public function messages()
        {
            return $this->hasMany('Message');
        }

    }

And the Mongodb-based Message model:

    use Jenssegers\Mongodb\Model as Eloquent;

    class Message extends Eloquent {

        protected $connection = 'mongodb';

        public function user()
        {
            return $this->belongsTo('User');
        }

    }

Jens Segers's avatar
Jens Segers committed
616
### Raw Expressions
Jens Segers's avatar
Jens Segers committed
617 618 619 620 621

These expressions will be injected directly into the query.

    User::whereRaw(array('age' => array('$gt' => 30, '$lt' => 40)))->get();

622
You can also perform raw expressions on the internal MongoCollection object. If this is executed on the model class, it will return a collection of models. If this is executed on the query builder, it will return the original response.
623

624 625
    // Returns a collection of User models.
    $models = User::raw(function($collection)
626 627 628 629
    {
        return $collection->find();
    });

630 631
    // Returns the original MongoCursor.
    $cursor = DB::collection('users')->raw(function($collection)
632 633 634 635
    {
        return $collection->find();
    });

636
Optional: if you don't pass a closure to the raw method, the internal MongoCollection object will be accessible:
637

638
    $model = User::raw()->findOne(array('age' => array('$lt' => 18)));
639

Jens Segers's avatar
Jens Segers committed
640
The internal MongoClient and MongoDB objects can be accessed like this:
641 642 643 644

    $client = DB::getMongoClient();
    $db = DB::getMongoDB();

645 646
### MongoDB specific operations

647 648 649 650 651 652
**Cursor timeout**

To prevent MongoCursorTimeout exceptions, you can manually set a timeout value that will be applied to the cursor:

    DB::collection('users')->timeout(-1)->get();

Jens Segers's avatar
Jens Segers committed
653 654 655 656 657 658 659
**Upsert**

Update or insert a document. Additional options for the update method are passed directly to the native update method.

    DB::collection('users')->where('name', 'John')
                           ->update($data, array('upsert' => true));

660 661
**Projections**

Jens Segers's avatar
Jens Segers committed
662
You can apply projections to your queries using the `project` method.
663 664 665

    DB::collection('items')->project(array('tags' => array('$slice' => 1)))->get();

Jens Segers's avatar
Jens Segers committed
666
**Push**
667

668
Add an items to an array.
669

Jens Segers's avatar
Jens Segers committed
670
    DB::collection('users')->where('name', 'John')->push('items', 'boots');
671
    DB::collection('users')->where('name', 'John')->push('messages', array('from' => 'Jane Doe', 'message' => 'Hi John'));
672

673 674 675 676
If you don't want duplicate items, set the third parameter to `true`:

    DB::collection('users')->where('name', 'John')->push('items', 'boots', true);

Jens Segers's avatar
Jens Segers committed
677
**Pull**
Jens Segers's avatar
Jens Segers committed
678

679
Remove an item from an array.
Jens Segers's avatar
Jens Segers committed
680

Jens Segers's avatar
Jens Segers committed
681
    DB::collection('users')->where('name', 'John')->pull('items', 'boots');
682
    DB::collection('users')->where('name', 'John')->pull('messages', array('from' => 'Jane Doe', 'message' => 'Hi John'));
Jens Segers's avatar
Jens Segers committed
683

Jens Segers's avatar
Jens Segers committed
684 685 686 687 688 689 690 691 692 693 694
**Unset**

Remove one or more fields from a document.

    DB::collection('users')->where('name', 'John')->unset('note');

You can also perform an unset on a model.

    $user = User::where('name', 'John')->first();
    $user->unset('note');

Jens Segers's avatar
Jens Segers committed
695
### Query Caching
Jens Segers's avatar
Jens Segers committed
696 697 698

You may easily cache the results of a query using the remember method:

Jens Segers's avatar
Jens Segers committed
699
    $users = User::remember(10)->get();
700

Jens Segers's avatar
Jens Segers committed
701 702
*From: http://laravel.com/docs/queries#caching-queries*

703 704 705 706 707
### Query Logging

By default, Laravel keeps a log in memory of all queries that have been run for the current request. However, in some cases, such as when inserting a large number of rows, this can cause the application to use excess memory. To disable the log, you may use the `disableQueryLog` method:

    DB::connection()->disableQueryLog();
Jens Segers's avatar
Jens Segers committed
708 709

*From: http://laravel.com/docs/database#query-logging*