README.md 25.9 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) [![Donate](https://img.shields.io/badge/donate-paypal-blue.svg)](https://www.paypal.me/jenssegers)
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

Jagdeep Singh's avatar
Jagdeep Singh committed
8 9 10
Table of contents
-----------------
* [Installation](#installation)
11
* [Upgrading](#upgrading)
Jagdeep Singh's avatar
Jagdeep Singh committed
12 13 14 15 16 17 18 19 20
* [Configuration](#configuration)
* [Eloquent](#eloquent)
* [Optional: Alias](#optional-alias)
* [Query Builder](#query-builder)
* [Schema](#schema)
* [Extensions](#extensions)
* [Troubleshooting](#troubleshooting)
* [Examples](#examples)

21 22 23
Installation
------------

24
Make sure you have the MongoDB PHP driver installed. You can find installation instructions at http://php.net/manual/en/mongodb.installation.php
25

Jens Segers's avatar
Jens Segers committed
26 27 28
**WARNING**: The old mongo PHP driver is not supported anymore in versions >= 3.0.

Installation using composer:
29

30
```
Anderson Andrade's avatar
Anderson Andrade committed
31 32
composer require jenssegers/mongodb
```
33

Jens Segers's avatar
Jens Segers committed
34
### Laravel version Compatibility
35

Jens Segers's avatar
Jens Segers committed
36
 Laravel  | Package
37 38 39
:---------|:----------
 4.2.x    | 2.0.x
 5.0.x    | 2.1.x
Jens Segers's avatar
Jens Segers committed
40
 5.1.x    | 2.2.x or 3.0.x
Jens Segers's avatar
Jens Segers committed
41
 5.2.x    | 2.3.x or 3.0.x
42 43
 5.3.x    | 3.1.x or 3.2.x
 5.4.x    | 3.2.x
dmitriy's avatar
dmitriy committed
44
 5.5.x    | 3.3.x
45

46
And add the service provider in `config/app.php`:
47

Anderson Andrade's avatar
Anderson Andrade committed
48
```php
49
Jenssegers\Mongodb\MongodbServiceProvider::class,
Anderson Andrade's avatar
Anderson Andrade committed
50
```
Jens Segers's avatar
Jens Segers committed
51

52 53 54
For usage with [Lumen](http://lumen.laravel.com), add the service provider in `bootstrap/app.php`. In this file, you will also need to enable Eloquent. You must however ensure that your call to `$app->withEloquent();` is **below** where you have registered the `MongodbServiceProvider`:

```php
55
$app->register(Jenssegers\Mongodb\MongodbServiceProvider::class);
56 57 58 59

$app->withEloquent();
```

Jens Segers's avatar
Jens Segers committed
60
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
61

62 63 64 65 66 67 68 69 70
For usage outside Laravel, check out the [Capsule manager](https://github.com/illuminate/database/blob/master/README.md) and add:

```php
$capsule->getDatabaseManager()->extend('mongodb', function($config)
{
    return new Jenssegers\Mongodb\Connection($config);
});
```

71 72 73
Upgrading
---------

Jens Segers's avatar
Jens Segers committed
74
#### Upgrading from version 2 to 3
75

Jens Segers's avatar
Jens Segers committed
76
In this new major release which supports the new mongodb PHP extension, we also moved the location of the Model class and replaced the MySQL model class with a trait.
77

Jens Segers's avatar
Jens Segers committed
78
Please change all `Jenssegers\Mongodb\Model` references to `Jenssegers\Mongodb\Eloquent\Model` either at the top of your model files, or your registered alias.
79

Jens Segers's avatar
Jens Segers committed
80 81
```php
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
82

Jens Segers's avatar
Jens Segers committed
83
class User extends Eloquent {}
84 85
```

Jens Segers's avatar
Jens Segers committed
86
If you are using hybrid relations, your MySQL classes should now extend the original Eloquent model class `Illuminate\Database\Eloquent\Model` instead of the removed `Jenssegers\Eloquent\Model`. Instead use the new `Jenssegers\Mongodb\Eloquent\HybridRelations` trait. This should make things more clear as there is only one single model class in this package.
Jens Segers's avatar
Jens Segers committed
87 88 89 90 91 92 93 94 95 96 97 98

```php
use Jenssegers\Mongodb\Eloquent\HybridRelations;

class User extends Eloquent {

    use HybridRelations;

    protected $connection = 'mysql';

}
```
99

100 101
Embedded relations now return an `Illuminate\Database\Eloquent\Collection` rather than a custom Collection class. If you were using one of the special methods that were available, convert them to Collection operations.

Jens Segers's avatar
Jens Segers committed
102 103 104 105
```php
$books = $user->books()->sortBy('title');
```

106 107 108 109 110 111 112 113 114
Testing
-------

To run the test for this package, run:

```
docker-compose up
```

Jens Segers's avatar
Jens Segers committed
115 116 117
Configuration
-------------

Diego Felix's avatar
Diego Felix committed
118
Change your default database connection name in `config/database.php`:
119

Anderson Andrade's avatar
Anderson Andrade committed
120
```php
121
'default' => env('DB_CONNECTION', 'mongodb'),
Anderson Andrade's avatar
Anderson Andrade committed
122
```
123 124

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

Anderson Andrade's avatar
Anderson Andrade committed
126
```php
Jens Segers's avatar
Jens Segers committed
127
'mongodb' => [
Anderson Andrade's avatar
Anderson Andrade committed
128
    'driver'   => 'mongodb',
129 130
    'host'     => env('DB_HOST', 'localhost'),
    'port'     => env('DB_PORT', 27017),
Jens Segers's avatar
Jens Segers committed
131 132
    'database' => env('DB_DATABASE'),
    'username' => env('DB_USERNAME'),
Jens Segers's avatar
Jens Segers committed
133
    'password' => env('DB_PASSWORD'),
134
    'options'  => [
Elmar's avatar
Elmar committed
135
        'database' => 'admin' // sets the authentication database required by mongo 3
Jens Segers's avatar
Jens Segers committed
136 137
    ]
],
Anderson Andrade's avatar
Anderson Andrade committed
138
```
Jens Segers's avatar
Jens Segers committed
139

140 141
You can connect to multiple servers or replica sets with the following configuration:

Anderson Andrade's avatar
Anderson Andrade committed
142
```php
Jens Segers's avatar
Jens Segers committed
143
'mongodb' => [
Anderson Andrade's avatar
Anderson Andrade committed
144
    'driver'   => 'mongodb',
Jens Segers's avatar
Jens Segers committed
145
    'host'     => ['server1', 'server2'],
146
    'port'     => env('DB_PORT', 27017),
Jens Segers's avatar
Jens Segers committed
147 148 149
    'database' => env('DB_DATABASE'),
    'username' => env('DB_USERNAME'),
    'password' => env('DB_PASSWORD'),
150 151 152
    'options'  => [
		'replicaSet' => 'replicaSetName'
	]
Jens Segers's avatar
Jens Segers committed
153
],
Anderson Andrade's avatar
Anderson Andrade committed
154
```
155

156 157 158 159 160 161 162 163 164 165 166 167
Alternatively, you can use MongoDB connection string:

```php
'mongodb' => [
    'driver'   => 'mongodb',
    'dsn' => env('DB_DSN'),
    'database' => env('DB_DATABASE'),
],
```

Please refer to MongoDB official docs for its URI format: https://docs.mongodb.com/manual/reference/connection-string/

168
Eloquent
169 170
--------

171
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
172

Anderson Andrade's avatar
Anderson Andrade committed
173
```php
174
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
Jens Segers's avatar
Jens Segers committed
175

Anderson Andrade's avatar
Anderson Andrade committed
176 177
class User extends Eloquent {}
```
178

179
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 collection name unless another name is explicitly specified. You may specify a custom collection (alias for table) by defining a `collection` property on your model:
180

Anderson Andrade's avatar
Anderson Andrade committed
181
```php
182
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
183

Anderson Andrade's avatar
Anderson Andrade committed
184
class User extends Eloquent {
185

Anderson Andrade's avatar
Anderson Andrade committed
186
    protected $collection = 'users_collection';
187

Anderson Andrade's avatar
Anderson Andrade committed
188 189
}
```
190

191
**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
192

Anderson Andrade's avatar
Anderson Andrade committed
193
```php
194
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
Jens Segers's avatar
Jens Segers committed
195

Anderson Andrade's avatar
Anderson Andrade committed
196
class MyModel extends Eloquent {
Jens Segers's avatar
Jens Segers committed
197

Anderson Andrade's avatar
Anderson Andrade committed
198
    protected $connection = 'mongodb';
199

Anderson Andrade's avatar
Anderson Andrade committed
200 201
}
```
202

Jens Segers's avatar
Jens Segers committed
203
Everything else (should) work just like the original Eloquent model. Read more about the Eloquent on http://laravel.com/docs/eloquent
204

Jens Segers's avatar
Jens Segers committed
205 206
### Optional: Alias

Diego Felix's avatar
Diego Felix committed
207
You may also register an alias for the MongoDB model by adding the following to the alias array in `config/app.php`:
Jens Segers's avatar
Jens Segers committed
208

Anderson Andrade's avatar
Anderson Andrade committed
209
```php
210
'Moloquent'       => Jenssegers\Mongodb\Eloquent\Model::class,
Anderson Andrade's avatar
Anderson Andrade committed
211
```
Jens Segers's avatar
Jens Segers committed
212

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

Anderson Andrade's avatar
Anderson Andrade committed
215 216 217
```php
class MyModel extends Moloquent {}
```
wikichua's avatar
wikichua committed
218

219 220 221
Query Builder
-------------

Jens Segers's avatar
Jens Segers committed
222
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
223

Anderson Andrade's avatar
Anderson Andrade committed
224 225
```php
$users = DB::collection('users')->get();
Jens Segers's avatar
Jens Segers committed
226

Anderson Andrade's avatar
Anderson Andrade committed
227 228
$user = DB::collection('users')->where('name', 'John')->first();
```
229

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

Anderson Andrade's avatar
Anderson Andrade committed
232 233 234
```php
$user = DB::connection('mongodb')->collection('users')->get();
```
Jens Segers's avatar
Jens Segers committed
235

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

238 239 240 241 242
Schema
------

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

Anderson Andrade's avatar
Anderson Andrade committed
243 244 245 246 247 248 249 250
```php
Schema::create('users', function($collection)
{
    $collection->index('name');

    $collection->unique('email');
});
```
251 252 253

Supported operations are:

Jens Segers's avatar
Jens Segers committed
254 255 256
 - create and drop
 - collection
 - hasCollection
257
 - index and dropIndex (compound indexes supported as well)
258
 - unique
259
 - background, sparse, expire, geospatial (MongoDB specific)
260

Jens Segers's avatar
Jens Segers committed
261
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
262

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
### Geospatial indexes

Geospatial indexes are handy for querying location-based documents. They come in two forms: `2d` and `2dsphere`. Use the schema builder to add these to a collection.

To add a `2d` index:

```php
Schema::create('users', function($collection)
{
    $collection->geospatial('name', '2d');
});
```

To add a `2dsphere` index:

```php
Schema::create('users', function($collection)
{
    $collection->geospatial('name', '2dsphere');
});
```

285 286
Extensions
----------
287

288
### Auth
289 290 291

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

Anderson Andrade's avatar
Anderson Andrade committed
292
```php
Jens Segers's avatar
Jens Segers committed
293
'Jenssegers\Mongodb\Auth\PasswordResetServiceProvider',
Anderson Andrade's avatar
Anderson Andrade committed
294
```
295 296 297

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.

298 299
### Queues

Jens Segers's avatar
Jens Segers committed
300
If you want to use MongoDB as your database backend, change the the driver in `config/queue.php`:
301 302 303

```php
'connections' => [
Jens Segers's avatar
Jens Segers committed
304
    'database' => [
305 306 307 308 309 310 311
        'driver' => 'mongodb',
        'table'  => 'jobs',
        'queue'  => 'default',
        'expire' => 60,
    ],
```

Fady Khalife's avatar
Fady Khalife committed
312 313 314 315 316 317 318 319 320
If you want to use MongoDB to handle failed jobs, change the database in `config/queue.php`:

```php
'failed' => [
    'database' => 'mongodb',
    'table'    => 'failed_jobs',
    ],
```

321
And add the service provider in `config/app.php`:
Fady Khalife's avatar
Fady Khalife committed
322 323 324 325 326

```php
Jenssegers\Mongodb\MongodbQueueServiceProvider::class,
```

327
### Sentry
328

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

331
### Sessions
Jens Segers's avatar
Jens Segers committed
332

333
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
334

Jens Segers's avatar
Jens Segers committed
335 336
Examples
--------
337

Jens Segers's avatar
Jens Segers committed
338 339
### Basic Usage

340 341
**Retrieving All Models**

Anderson Andrade's avatar
Anderson Andrade committed
342 343 344
```php
$users = User::all();
```
345 346 347

**Retrieving A Record By Primary Key**

Anderson Andrade's avatar
Anderson Andrade committed
348 349 350
```php
$user = User::find('517c43667db388101e00000f');
```
351 352 353

**Wheres**

Anderson Andrade's avatar
Anderson Andrade committed
354 355 356
```php
$users = User::where('votes', '>', 100)->take(10)->get();
```
357 358 359

**Or Statements**

Anderson Andrade's avatar
Anderson Andrade committed
360 361 362
```php
$users = User::where('votes', '>', 100)->orWhere('name', 'John')->get();
```
363

364 365
**And Statements**

Anderson Andrade's avatar
Anderson Andrade committed
366 367 368
```php
$users = User::where('votes', '>', 100)->where('name', '=', 'John')->get();
```
Jens Segers's avatar
Jens Segers committed
369

370 371
**Using Where In With An Array**

Anderson Andrade's avatar
Anderson Andrade committed
372
```php
Jens Segers's avatar
Jens Segers committed
373
$users = User::whereIn('age', [16, 18, 20])->get();
Anderson Andrade's avatar
Anderson Andrade committed
374
```
Jens Segers's avatar
Jens Segers committed
375

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

Jens Segers's avatar
Jens Segers committed
378 379
**Using Where Between**

Anderson Andrade's avatar
Anderson Andrade committed
380
```php
Jens Segers's avatar
Jens Segers committed
381
$users = User::whereBetween('votes', [1, 100])->get();
Anderson Andrade's avatar
Anderson Andrade committed
382
```
Jens Segers's avatar
Jens Segers committed
383

Jens Segers's avatar
Jens Segers committed
384 385
**Where null**

Anderson Andrade's avatar
Anderson Andrade committed
386 387 388
```php
$users = User::whereNull('updated_at')->get();
```
389 390 391

**Order By**

Anderson Andrade's avatar
Anderson Andrade committed
392 393 394
```php
$users = User::orderBy('name', 'desc')->get();
```
395

Jens Segers's avatar
Jens Segers committed
396 397
**Offset & Limit**

Anderson Andrade's avatar
Anderson Andrade committed
398 399 400
```php
$users = User::skip(10)->take(5)->get();
```
Jens Segers's avatar
Jens Segers committed
401

Jens Segers's avatar
Jens Segers committed
402 403 404 405
**Distinct**

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

Anderson Andrade's avatar
Anderson Andrade committed
406
```php
Jens Segers's avatar
Jens Segers committed
407
$users = User::distinct()->get(['name']);
Anderson Andrade's avatar
Anderson Andrade committed
408 409 410
// or
$users = User::distinct('name')->get();
```
Jens Segers's avatar
Jens Segers committed
411

Jens Segers's avatar
Jens Segers committed
412 413
Distinct can be combined with **where**:

Anderson Andrade's avatar
Anderson Andrade committed
414 415 416
```php
$users = User::where('active', true)->distinct('name')->get();
```
Jens Segers's avatar
Jens Segers committed
417

418 419
**Advanced Wheres**

Anderson Andrade's avatar
Anderson Andrade committed
420 421 422 423 424 425 426 427
```php
$users = User::where('name', '=', 'John')->orWhere(function($query)
    {
        $query->where('votes', '>', 100)
              ->where('title', '<>', 'Admin');
    })
    ->get();
```
428

Jens Segers's avatar
Jens Segers committed
429 430
**Group By**

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

Anderson Andrade's avatar
Anderson Andrade committed
433
```php
Jens Segers's avatar
Jens Segers committed
434
$users = Users::groupBy('title')->get(['title', 'name']);
Anderson Andrade's avatar
Anderson Andrade committed
435
```
Jens Segers's avatar
Jens Segers committed
436 437

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

439 440
*Aggregations are only available for MongoDB versions greater than 2.2.*

Anderson Andrade's avatar
Anderson Andrade committed
441 442 443 444 445 446 447
```php
$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
448 449 450

Aggregations can be combined with **where**:

Anderson Andrade's avatar
Anderson Andrade committed
451 452 453
```php
$sold = Orders::where('sold', true)->sum('price');
```
Jens Segers's avatar
Jens Segers committed
454

455 456 457 458 459 460 461 462 463
Aggregations can be also used on subdocuments:

```php
$total = Order::max('suborder.price');
...
```

**NOTE**: this aggreagtion only works with single subdocuments (like embedsOne) not subdocument arrays (like embedsMany)

Jens Segers's avatar
Jens Segers committed
464 465
**Like**

Anderson Andrade's avatar
Anderson Andrade committed
466 467 468
```php
$user = Comment::where('body', 'like', '%spam%')->get();
```
Jens Segers's avatar
Jens Segers committed
469

470
**Incrementing or decrementing a value of a column**
471

472
Perform increments or decrements (default 1) on specified attributes:
473

Anderson Andrade's avatar
Anderson Andrade committed
474 475 476 477
```php
User::where('name', 'John Doe')->increment('age');
User::where('name', 'Jaques')->decrement('weight', 50);
```
478

479
The number of updated objects is returned:
480

Anderson Andrade's avatar
Anderson Andrade committed
481 482 483
```php
$count = User->increment('age');
```
484

485
You may also specify additional columns to update:
486

Anderson Andrade's avatar
Anderson Andrade committed
487
```php
Jens Segers's avatar
Jens Segers committed
488 489
User::where('age', '29')->increment('age', 1, ['group' => 'thirty something']);
User::where('bmi', 30)->decrement('bmi', 1, ['category' => 'overweight']);
Anderson Andrade's avatar
Anderson Andrade committed
490
```
Jens Segers's avatar
Jens Segers committed
491

492 493 494 495
**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:

Anderson Andrade's avatar
Anderson Andrade committed
496
```php
497
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
498

Anderson Andrade's avatar
Anderson Andrade committed
499
class User extends Eloquent {
500

501
    use SoftDeletes;
502

Anderson Andrade's avatar
Anderson Andrade committed
503
    protected $dates = ['deleted_at'];
504

Anderson Andrade's avatar
Anderson Andrade committed
505 506
}
```
507 508 509

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

510 511 512 513 514 515
### MongoDB specific operators

**Exists**

Matches documents that have the specified field.

Anderson Andrade's avatar
Anderson Andrade committed
516 517 518
```php
User::where('age', 'exists', true)->get();
```
519 520 521 522 523

**All**

Matches arrays that contain all elements specified in the query.

Anderson Andrade's avatar
Anderson Andrade committed
524
```php
Jens Segers's avatar
Jens Segers committed
525
User::where('roles', 'all', ['moderator', 'author'])->get();
Anderson Andrade's avatar
Anderson Andrade committed
526
```
527 528 529 530 531

**Size**

Selects documents if the array field is a specified size.

Anderson Andrade's avatar
Anderson Andrade committed
532 533 534
```php
User::where('tags', 'size', 3)->get();
```
535

Jens Segers's avatar
Jens Segers committed
536 537 538 539
**Regex**

Selects documents where values match a specified regular expression.

Anderson Andrade's avatar
Anderson Andrade committed
540
```php
541
User::where('name', 'regex', new \MongoDB\BSON\Regex("/.*doe/i"))->get();
Anderson Andrade's avatar
Anderson Andrade committed
542
```
Jens Segers's avatar
Jens Segers committed
543

544
**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 MongoDB\BSON\Regex object.
Jens Segers's avatar
Jens Segers committed
545

Anderson Andrade's avatar
Anderson Andrade committed
546 547 548
```php
User::where('name', 'regexp', '/.*doe/i'))->get();
```
Jens Segers's avatar
Jens Segers committed
549 550 551

And the inverse:

Anderson Andrade's avatar
Anderson Andrade committed
552 553 554
```php
User::where('name', 'not regexp', '/.*doe/i'))->get();
```
Jens Segers's avatar
Jens Segers committed
555

556 557 558 559
**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

Anderson Andrade's avatar
Anderson Andrade committed
560 561 562
```php
User::where('age', 'type', 2)->get();
```
563 564 565 566 567

**Mod**

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

Anderson Andrade's avatar
Anderson Andrade committed
568
```php
Jens Segers's avatar
Jens Segers committed
569
User::where('age', 'mod', [10, 0])->get();
Anderson Andrade's avatar
Anderson Andrade committed
570
```
571

572 573 574 575 576 577 578 579 580 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 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
**Near**

**NOTE:** Specify coordinates in this order: `longitude, latitude`.

```php
$users = User::where('location', 'near', [
	'$geometry' => [
        'type' => 'Point',
	    'coordinates' => [
	        -0.1367563,
            51.5100913,
        ],
    ],
    '$maxDistance' => 50,
]);
```

**GeoWithin**

```php
$users = User::where('location', 'geoWithin', [
	'$geometry' => [
        'type' => 'Polygon',
	    'coordinates' => [[
            [
                -0.1450383,
                51.5069158,
            ],       
            [
                -0.1367563,
                51.5100913,
            ],       
            [
                -0.1270247,
                51.5013233,
            ],  
            [
                -0.1450383,
                51.5069158,
            ],
        ]],
    ],
]);
```

**GeoIntersects**

```php
$locations = Location::where('location', 'geoIntersects', [
    '$geometry' => [
        'type' => 'LineString',
        'coordinates' => [
            [
                -0.144044,
                51.515215,
            ],
            [
                -0.129545,
                51.507864,
            ],
        ],
    ],
]);
```


638 639 640 641
**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
642 643
### Inserts, updates and deletes

644 645 646 647
Inserting, updating and deleting records works just like the original Eloquent.

**Saving a new model**

Anderson Andrade's avatar
Anderson Andrade committed
648 649 650 651 652
```php
$user = new User;
$user->name = 'John';
$user->save();
```
653 654 655

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

Anderson Andrade's avatar
Anderson Andrade committed
656
```php
Jens Segers's avatar
Jens Segers committed
657
User::create(['name' => 'John']);
Anderson Andrade's avatar
Anderson Andrade committed
658
```
659 660 661

**Updating a model**

Mohit Mamoria's avatar
Mohit Mamoria committed
662
To update a model, you may retrieve it, change an attribute, and use the save method.
663

Anderson Andrade's avatar
Anderson Andrade committed
664 665 666 667 668
```php
$user = User::first();
$user->email = 'john@foo.com';
$user->save();
```
669 670 671 672 673 674 675

*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:

Anderson Andrade's avatar
Anderson Andrade committed
676 677 678 679
```php
$user = User::first();
$user->delete();
```
680 681 682

Or deleting a model by its key:

Anderson Andrade's avatar
Anderson Andrade committed
683 684 685
```php
User::destroy('517c43667db388101e00000f');
```
686 687

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

689 690 691 692 693 694
### 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:

Anderson Andrade's avatar
Anderson Andrade committed
695
```php
696
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
697

Anderson Andrade's avatar
Anderson Andrade committed
698
class User extends Eloquent {
699

Jens Segers's avatar
Jens Segers committed
700
    protected $dates = ['birthday'];
701

Anderson Andrade's avatar
Anderson Andrade committed
702 703
}
```
704 705 706

Which allows you to execute queries like:

Anderson Andrade's avatar
Anderson Andrade committed
707 708 709
```php
$users = User::where('birthday', '>', new DateTime('-18 years'))->get();
```
710

Jens Segers's avatar
Jens Segers committed
711
### Relations
Jens Segers's avatar
Jens Segers committed
712

Jens Segers's avatar
Jens Segers committed
713
Supported relations are:
Jens Segers's avatar
Jens Segers committed
714 715 716 717

 - hasOne
 - hasMany
 - belongsTo
718
 - belongsToMany
719 720
 - embedsOne
 - embedsMany
721

Jens Segers's avatar
Jens Segers committed
722 723
Example:

Anderson Andrade's avatar
Anderson Andrade committed
724
```php
725
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
Jens Segers's avatar
Jens Segers committed
726

Anderson Andrade's avatar
Anderson Andrade committed
727
class User extends Eloquent {
Jens Segers's avatar
Jens Segers committed
728

Anderson Andrade's avatar
Anderson Andrade committed
729 730 731
    public function items()
    {
        return $this->hasMany('Item');
Jens Segers's avatar
Jens Segers committed
732 733
    }

Anderson Andrade's avatar
Anderson Andrade committed
734 735
}
```
Jens Segers's avatar
Jens Segers committed
736 737

And the inverse relation:
Jens Segers's avatar
Jens Segers committed
738

Anderson Andrade's avatar
Anderson Andrade committed
739
```php
740
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
Jens Segers's avatar
Jens Segers committed
741

Anderson Andrade's avatar
Anderson Andrade committed
742
class Item extends Eloquent {
Jens Segers's avatar
Jens Segers committed
743

Anderson Andrade's avatar
Anderson Andrade committed
744 745 746
    public function user()
    {
        return $this->belongsTo('User');
Jens Segers's avatar
Jens Segers committed
747 748
    }

Anderson Andrade's avatar
Anderson Andrade committed
749 750
}
```
Jens Segers's avatar
Jens Segers committed
751 752 753

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`:

Anderson Andrade's avatar
Anderson Andrade committed
754
```php
755
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
Jens Segers's avatar
Jens Segers committed
756

Anderson Andrade's avatar
Anderson Andrade committed
757
class User extends Eloquent {
Jens Segers's avatar
Jens Segers committed
758

Anderson Andrade's avatar
Anderson Andrade committed
759 760
    public function groups()
    {
761
        return $this->belongsToMany('Group', null, 'user_ids', 'group_ids');
Jens Segers's avatar
Jens Segers committed
762 763
    }

Anderson Andrade's avatar
Anderson Andrade committed
764 765 766
}
```

Jens Segers's avatar
Jens Segers committed
767

Shubhamoy's avatar
Shubhamoy committed
768
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
769

770 771
### EmbedsMany Relations

Jens Segers's avatar
Jens Segers committed
772
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.
773

774 775
**REMEMBER**: these relations return Eloquent collections, they don't return query builder objects!

Anderson Andrade's avatar
Anderson Andrade committed
776
```php
777
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
778

Anderson Andrade's avatar
Anderson Andrade committed
779
class User extends Eloquent {
780

Anderson Andrade's avatar
Anderson Andrade committed
781 782 783
    public function books()
    {
        return $this->embedsMany('Book');
784 785
    }

Anderson Andrade's avatar
Anderson Andrade committed
786 787
}
```
Jens Segers's avatar
Jens Segers committed
788

Jens Segers's avatar
Jens Segers committed
789
You access the embedded models through the dynamic property:
790

Anderson Andrade's avatar
Anderson Andrade committed
791 792 793
```php
$books = User::first()->books;
```
794

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

Anderson Andrade's avatar
Anderson Andrade committed
797 798 799
```php
$user = $book->user;
```
Jens Segers's avatar
Jens Segers committed
800

Jens Segers's avatar
Jens Segers committed
801
Inserting and updating embedded models works similar to the `hasMany` relation:
802

Anderson Andrade's avatar
Anderson Andrade committed
803
```php
Jens Segers's avatar
Jens Segers committed
804
$book = new Book(['title' => 'A Game of Thrones']);
805

Anderson Andrade's avatar
Anderson Andrade committed
806
$user = User::first();
807

Anderson Andrade's avatar
Anderson Andrade committed
808 809
$book = $user->books()->save($book);
// or
Jens Segers's avatar
Jens Segers committed
810
$book = $user->books()->create(['title' => 'A Game of Thrones'])
Anderson Andrade's avatar
Anderson Andrade committed
811
```
812

Jens Segers's avatar
Jens Segers committed
813
You can update embedded models using their `save` method (available since release 2.0.0):
814

Anderson Andrade's avatar
Anderson Andrade committed
815 816
```php
$book = $user->books()->first();
817

Anderson Andrade's avatar
Anderson Andrade committed
818
$book->title = 'A Game of Thrones';
Jens Segers's avatar
Jens Segers committed
819

Anderson Andrade's avatar
Anderson Andrade committed
820 821
$book->save();
```
Jens Segers's avatar
Jens Segers committed
822

Jens Segers's avatar
Jens Segers committed
823
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
824

Anderson Andrade's avatar
Anderson Andrade committed
825 826
```php
$book = $user->books()->first();
Jens Segers's avatar
Jens Segers committed
827

Anderson Andrade's avatar
Anderson Andrade committed
828 829 830 831
$book->delete();
// or
$user->books()->destroy($book);
```
832

Jens Segers's avatar
Jens Segers committed
833
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:
834

Anderson Andrade's avatar
Anderson Andrade committed
835 836
```php
$user->books()->associate($book);
837

Anderson Andrade's avatar
Anderson Andrade committed
838 839
$user->save();
```
840

Jens Segers's avatar
Jens Segers committed
841
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:
842

Anderson Andrade's avatar
Anderson Andrade committed
843 844 845
```php
return $this->embedsMany('Book', 'local_key');
```
846

847
Embedded relations will return a Collection of embedded items instead of a query builder. Check out the available operations here: https://laravel.com/docs/master/collections
Jens Segers's avatar
Jens Segers committed
848

849 850
### EmbedsOne Relations

Jens Segers's avatar
Jens Segers committed
851
The embedsOne relation is similar to the EmbedsMany relation, but only embeds a single model.
852

Anderson Andrade's avatar
Anderson Andrade committed
853
```php
854
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
855

Anderson Andrade's avatar
Anderson Andrade committed
856
class Book extends Eloquent {
857

Anderson Andrade's avatar
Anderson Andrade committed
858 859 860
    public function author()
    {
        return $this->embedsOne('Author');
861 862
    }

Anderson Andrade's avatar
Anderson Andrade committed
863 864
}
```
Jens Segers's avatar
Jens Segers committed
865

Jens Segers's avatar
Jens Segers committed
866
You access the embedded models through the dynamic property:
867

Anderson Andrade's avatar
Anderson Andrade committed
868 869 870
```php
$author = Book::first()->author;
```
871

Jens Segers's avatar
Jens Segers committed
872
Inserting and updating embedded models works similar to the `hasOne` relation:
873

Anderson Andrade's avatar
Anderson Andrade committed
874
```php
Jens Segers's avatar
Jens Segers committed
875
$author = new Author(['name' => 'John Doe']);
876

Anderson Andrade's avatar
Anderson Andrade committed
877
$book = Books::first();
Jens Segers's avatar
Jens Segers committed
878

Anderson Andrade's avatar
Anderson Andrade committed
879 880
$author = $book->author()->save($author);
// or
Jens Segers's avatar
Jens Segers committed
881
$author = $book->author()->create(['name' => 'John Doe']);
Anderson Andrade's avatar
Anderson Andrade committed
882
```
Jens Segers's avatar
Jens Segers committed
883

Jens Segers's avatar
Jens Segers committed
884
You can update the embedded model using the `save` method (available since release 2.0.0):
Jens Segers's avatar
Jens Segers committed
885

Anderson Andrade's avatar
Anderson Andrade committed
886 887
```php
$author = $book->author;
Jens Segers's avatar
Jens Segers committed
888

Anderson Andrade's avatar
Anderson Andrade committed
889 890 891
$author->name = 'Jane Doe';
$author->save();
```
Jens Segers's avatar
Jens Segers committed
892

Jens Segers's avatar
Jens Segers committed
893
You can replace the embedded model with a new model like this:
Jens Segers's avatar
Jens Segers committed
894

Anderson Andrade's avatar
Anderson Andrade committed
895
```php
Jens Segers's avatar
Jens Segers committed
896
$newAuthor = new Author(['name' => 'Jane Doe']);
Anderson Andrade's avatar
Anderson Andrade committed
897 898
$book->author()->save($newAuthor);
```
899

900 901
### MySQL Relations

902
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 use the `Jenssegers\Mongodb\Eloquent\HybridRelations` trait. Note that this functionality only works for hasOne, hasMany and belongsTo relations.
903 904 905

Example SQL-based User model:

Anderson Andrade's avatar
Anderson Andrade committed
906
```php
907
use Jenssegers\Mongodb\Eloquent\HybridRelations;
908

Anderson Andrade's avatar
Anderson Andrade committed
909
class User extends Eloquent {
910

911 912
    use HybridRelations;

Anderson Andrade's avatar
Anderson Andrade committed
913
    protected $connection = 'mysql';
914

Anderson Andrade's avatar
Anderson Andrade committed
915 916 917
    public function messages()
    {
        return $this->hasMany('Message');
918 919
    }

Anderson Andrade's avatar
Anderson Andrade committed
920 921
}
```
922 923 924

And the Mongodb-based Message model:

Anderson Andrade's avatar
Anderson Andrade committed
925
```php
926
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
927

Anderson Andrade's avatar
Anderson Andrade committed
928
class Message extends Eloquent {
929

Anderson Andrade's avatar
Anderson Andrade committed
930
    protected $connection = 'mongodb';
931

Anderson Andrade's avatar
Anderson Andrade committed
932 933 934
    public function user()
    {
        return $this->belongsTo('User');
935 936
    }

Anderson Andrade's avatar
Anderson Andrade committed
937 938
}
```
Jens Segers's avatar
Jens Segers committed
939

Jens Segers's avatar
Jens Segers committed
940
### Raw Expressions
Jens Segers's avatar
Jens Segers committed
941 942 943

These expressions will be injected directly into the query.

Anderson Andrade's avatar
Anderson Andrade committed
944
```php
Rahul Kalkani's avatar
Rahul Kalkani committed
945
User::whereRaw(['age' => array('$gt' => 30, '$lt' => 40)])->get();
Anderson Andrade's avatar
Anderson Andrade committed
946
```
Jens Segers's avatar
Jens Segers committed
947

948
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.
949

Anderson Andrade's avatar
Anderson Andrade committed
950 951 952 953 954 955 956 957 958 959 960 961 962
```php
// Returns a collection of User models.
$models = User::raw(function($collection)
{
    return $collection->find();
});

// Returns the original MongoCursor.
$cursor = DB::collection('users')->raw(function($collection)
{
    return $collection->find();
});
```
963

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

Anderson Andrade's avatar
Anderson Andrade committed
966
```php
967
$model = User::raw()->findOne(['age' => array('$lt' => 18)]);
Anderson Andrade's avatar
Anderson Andrade committed
968
```
969

Jens Segers's avatar
Jens Segers committed
970
The internal MongoClient and MongoDB objects can be accessed like this:
971

Anderson Andrade's avatar
Anderson Andrade committed
972 973 974 975
```php
$client = DB::getMongoClient();
$db = DB::getMongoDB();
```
976

977 978
### MongoDB specific operations

979 980 981 982
**Cursor timeout**

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

Anderson Andrade's avatar
Anderson Andrade committed
983 984 985
```php
DB::collection('users')->timeout(-1)->get();
```
986

Jens Segers's avatar
Jens Segers committed
987 988 989 990
**Upsert**

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

Anderson Andrade's avatar
Anderson Andrade committed
991 992
```php
DB::collection('users')->where('name', 'John')
Jens Segers's avatar
Jens Segers committed
993
                       ->update($data, ['upsert' => true]);
Anderson Andrade's avatar
Anderson Andrade committed
994
```
Jens Segers's avatar
Jens Segers committed
995

996 997
**Projections**

Jens Segers's avatar
Jens Segers committed
998
You can apply projections to your queries using the `project` method.
999

Anderson Andrade's avatar
Anderson Andrade committed
1000
```php
Johnny Dao's avatar
Johnny Dao committed
1001 1002
DB::collection('items')->project(['tags' => ['$slice' => 1]])->get();
DB::collection('items')->project(['tags' => ['$slice' => [3, 7]]])->get();
Anderson Andrade's avatar
Anderson Andrade committed
1003
```
1004

Jagdeep Singh's avatar
Jagdeep Singh committed
1005 1006 1007 1008
**Projections with Pagination**

```php
$limit = 25;
Jens Segers's avatar
Jens Segers committed
1009
$projections = ['id', 'name'];
Jagdeep Singh's avatar
Jagdeep Singh committed
1010 1011 1012 1013
DB::collection('items')->paginate($limit, $projections);
```


Jens Segers's avatar
Jens Segers committed
1014
**Push**
1015

1016
Add an items to an array.
1017

Anderson Andrade's avatar
Anderson Andrade committed
1018 1019
```php
DB::collection('users')->where('name', 'John')->push('items', 'boots');
Jens Segers's avatar
Jens Segers committed
1020
DB::collection('users')->where('name', 'John')->push('messages', ['from' => 'Jane Doe', 'message' => 'Hi John']);
Anderson Andrade's avatar
Anderson Andrade committed
1021
```
1022

1023 1024
If you don't want duplicate items, set the third parameter to `true`:

Anderson Andrade's avatar
Anderson Andrade committed
1025 1026 1027
```php
DB::collection('users')->where('name', 'John')->push('items', 'boots', true);
```
1028

Jens Segers's avatar
Jens Segers committed
1029
**Pull**
Jens Segers's avatar
Jens Segers committed
1030

1031
Remove an item from an array.
Jens Segers's avatar
Jens Segers committed
1032

Anderson Andrade's avatar
Anderson Andrade committed
1033 1034
```php
DB::collection('users')->where('name', 'John')->pull('items', 'boots');
Jens Segers's avatar
Jens Segers committed
1035
DB::collection('users')->where('name', 'John')->pull('messages', ['from' => 'Jane Doe', 'message' => 'Hi John']);
Anderson Andrade's avatar
Anderson Andrade committed
1036
```
Jens Segers's avatar
Jens Segers committed
1037

Jens Segers's avatar
Jens Segers committed
1038 1039 1040 1041
**Unset**

Remove one or more fields from a document.

Anderson Andrade's avatar
Anderson Andrade committed
1042 1043 1044
```php
DB::collection('users')->where('name', 'John')->unset('note');
```
Jens Segers's avatar
Jens Segers committed
1045 1046 1047

You can also perform an unset on a model.

Anderson Andrade's avatar
Anderson Andrade committed
1048 1049 1050 1051
```php
$user = User::where('name', 'John')->first();
$user->unset('note');
```
Jens Segers's avatar
Jens Segers committed
1052

Jens Segers's avatar
Jens Segers committed
1053
### Query Caching
Jens Segers's avatar
Jens Segers committed
1054 1055 1056

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

Anderson Andrade's avatar
Anderson Andrade committed
1057 1058 1059
```php
$users = User::remember(10)->get();
```
1060

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

1063 1064 1065 1066
### 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:

Anderson Andrade's avatar
Anderson Andrade committed
1067 1068 1069
```php
DB::connection()->disableQueryLog();
```
Jens Segers's avatar
Jens Segers committed
1070 1071

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