From 7af79132502a5f1d63c78557fd333fa002446230 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Tue, 9 Jan 2024 12:00:35 -0500 Subject: [PATCH 1/3] DOCSP-35148: Convert docs to Snooty RST --- docs/eloquent-models.md | 464 --------------------------- docs/eloquent-models.txt | 522 ++++++++++++++++++++++++++++++ docs/index.txt | 70 ++++ docs/install.md | 64 ---- docs/install.txt | 82 +++++ docs/query-builder.md | 602 ----------------------------------- docs/query-builder.txt | 569 +++++++++++++++++++++++++++++++++ docs/queues.md | 34 -- docs/queues.txt | 46 +++ docs/transactions.md | 56 ---- docs/transactions.txt | 79 +++++ docs/upgrade.md | 19 -- docs/upgrade.txt | 49 +++ docs/user-authentication.md | 15 - docs/user-authentication.txt | 24 ++ 15 files changed, 1441 insertions(+), 1254 deletions(-) delete mode 100644 docs/eloquent-models.md create mode 100644 docs/eloquent-models.txt create mode 100644 docs/index.txt delete mode 100644 docs/install.md create mode 100644 docs/install.txt delete mode 100644 docs/query-builder.md create mode 100644 docs/query-builder.txt delete mode 100644 docs/queues.md create mode 100644 docs/queues.txt delete mode 100644 docs/transactions.md create mode 100644 docs/transactions.txt delete mode 100644 docs/upgrade.md create mode 100644 docs/upgrade.txt delete mode 100644 docs/user-authentication.md create mode 100644 docs/user-authentication.txt diff --git a/docs/eloquent-models.md b/docs/eloquent-models.md deleted file mode 100644 index c64bb76b6..000000000 --- a/docs/eloquent-models.md +++ /dev/null @@ -1,464 +0,0 @@ -Eloquent Models -=============== - -Previous: [Installation and configuration](install.md) - -This package includes a MongoDB enabled Eloquent class that you can use to define models for corresponding collections. - -### Extending the base model - -To get started, create a new model class in your `app\Models\` directory. - -```php -namespace App\Models; - -use MongoDB\Laravel\Eloquent\Model; - -class Book extends Model -{ - // -} -``` - -Just like a normal model, the MongoDB model class will know which collection to use based on the model name. For `Book`, the collection `books` will be used. - -To change the collection, pass the `$collection` property: - -```php -use MongoDB\Laravel\Eloquent\Model; - -class Book extends Model -{ - protected $collection = 'my_books_collection'; -} -``` - -**NOTE:** MongoDB documents are automatically stored with a unique ID that is stored in the `_id` property. If you wish to use your own ID, substitute the `$primaryKey` property and set it to your own primary key attribute name. - -```php -use MongoDB\Laravel\Eloquent\Model; - -class Book extends Model -{ - protected $primaryKey = 'id'; -} - -// MongoDB will also create _id, but the 'id' property will be used for primary key actions like find(). -Book::create(['id' => 1, 'title' => 'The Fault in Our Stars']); -``` - -Likewise, you may define a `connection` property to override the name of the database connection that should be used when utilizing the model. - -```php -use MongoDB\Laravel\Eloquent\Model; - -class Book extends Model -{ - protected $connection = 'mongodb'; -} -``` - -### Soft Deletes - -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 delete for a model, apply the `MongoDB\Laravel\Eloquent\SoftDeletes` Trait to the model: - -```php -use MongoDB\Laravel\Eloquent\SoftDeletes; - -class User extends Model -{ - use SoftDeletes; -} -``` - -For more information check [Laravel Docs about Soft Deleting](http://laravel.com/docs/eloquent#soft-deleting). - -### Prunable - -`Prunable` and `MassPrunable` traits are Laravel features to automatically remove models from your database. You can use -`Illuminate\Database\Eloquent\Prunable` trait to remove models one by one. If you want to remove models in bulk, you need -to use the `MongoDB\Laravel\Eloquent\MassPrunable` trait instead: it will be more performant but can break links with -other documents as it does not load the models. - -```php -use MongoDB\Laravel\Eloquent\Model; -use MongoDB\Laravel\Eloquent\MassPrunable; - -class Book extends Model -{ - use MassPrunable; -} -``` - -For more information check [Laravel Docs about Pruning Models](http://laravel.com/docs/eloquent#pruning-models). - -### Dates - -Eloquent allows you to work with Carbon or DateTime objects instead of MongoDate objects. Internally, these dates will be converted to MongoDate objects when saved to the database. - -```php -use MongoDB\Laravel\Eloquent\Model; - -class User extends Model -{ - protected $casts = ['birthday' => 'datetime']; -} -``` - -This allows you to execute queries like this: - -```php -$users = User::where( - 'birthday', '>', - new DateTime('-18 years') -)->get(); -``` - -### Extending the Authenticatable base model - -This package includes a MongoDB Authenticatable Eloquent class `MongoDB\Laravel\Auth\User` that you can use to replace the default Authenticatable class `Illuminate\Foundation\Auth\User` for your `User` model. - -```php -use MongoDB\Laravel\Auth\User as Authenticatable; - -class User extends Authenticatable -{ - -} -``` - -### Guarding attributes - -When choosing between guarding attributes or marking some as fillable, Taylor Otwell prefers the fillable route. -This is in light of [recent security issues described here](https://blog.laravel.com/security-release-laravel-61835-7240). - -Keep in mind guarding still works, but you may experience unexpected behavior. - -Schema ------- - -The database driver also has (limited) schema builder support. You can easily manipulate collections and set indexes. - -### Basic Usage - -```php -Schema::create('users', function ($collection) { - $collection->index('name'); - $collection->unique('email'); -}); -``` - -You can also pass all the parameters specified [in the MongoDB docs](https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#options-for-all-index-types) to the `$options` parameter: - -```php -Schema::create('users', function ($collection) { - $collection->index( - 'username', - null, - null, - [ - 'sparse' => true, - 'unique' => true, - 'background' => true, - ] - ); -}); -``` - -Inherited operations: - -- create and drop -- collection -- hasCollection -- index and dropIndex (compound indexes supported as well) -- unique - -MongoDB specific operations: - -- background -- sparse -- expire -- geospatial - -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 [Laravel Docs](https://laravel.com/docs/10.x/migrations#tables) - -### 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. - -```php -Schema::create('bars', function ($collection) { - $collection->geospatial('location', '2d'); -}); -``` - -To add a `2dsphere` index: - -```php -Schema::create('bars', function ($collection) { - $collection->geospatial('location', '2dsphere'); -}); -``` - -Relationships -------------- - -### Basic Usage - -The only available relationships are: - -- hasOne -- hasMany -- belongsTo -- belongsToMany - -The MongoDB-specific relationships are: - -- embedsOne -- embedsMany - -Here is a small example: - -```php -use MongoDB\Laravel\Eloquent\Model; - -class User extends Model -{ - public function items() - { - return $this->hasMany(Item::class); - } -} -``` - -The inverse relation of `hasMany` is `belongsTo`: - -```php -use MongoDB\Laravel\Eloquent\Model; - -class Item extends Model -{ - public function user() - { - return $this->belongsTo(User::class); - } -} -``` - -### belongsToMany and pivots - -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`: - -```php -use MongoDB\Laravel\Eloquent\Model; - -class User extends Model -{ - public function groups() - { - return $this->belongsToMany( - Group::class, null, 'user_ids', 'group_ids' - ); - } -} -``` - -### EmbedsMany Relationship - -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. - -**REMEMBER**: These relations return Eloquent collections, they don't return query builder objects! - -```php -use MongoDB\Laravel\Eloquent\Model; - -class User extends Model -{ - public function books() - { - return $this->embedsMany(Book::class); - } -} -``` - -You can access the embedded models through the dynamic property: - -```php -$user = User::first(); - -foreach ($user->books as $book) { - // -} -``` - -The inverse relation is auto*magically* available. You don't need to define this reverse relation. - -```php -$book = Book::first(); - -$user = $book->user; -``` - -Inserting and updating embedded models works similar to the `hasMany` relation: - -```php -$book = $user->books()->save( - new Book(['title' => 'A Game of Thrones']) -); - -// or -$book = - $user->books() - ->create(['title' => 'A Game of Thrones']); -``` - -You can update embedded models using their `save` method (available since release 2.0.0): - -```php -$book = $user->books()->first(); - -$book->title = 'A Game of Thrones'; -$book->save(); -``` - -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): - -```php -$book->delete(); - -// Similar operation -$user->books()->destroy($book); -``` - -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: - -```php -$user->books()->associate($book); -$user->save(); -``` - -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: - -```php -use MongoDB\Laravel\Eloquent\Model; - -class User extends Model -{ - public function books() - { - return $this->embedsMany(Book::class, 'local_key'); - } -} -``` - -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 - -### EmbedsOne Relationship - -The embedsOne relation is similar to the embedsMany relation, but only embeds a single model. - -```php -use MongoDB\Laravel\Eloquent\Model; - -class Book extends Model -{ - public function author() - { - return $this->embedsOne(Author::class); - } -} -``` - -You can access the embedded models through the dynamic property: - -```php -$book = Book::first(); -$author = $book->author; -``` - -Inserting and updating embedded models works similar to the `hasOne` relation: - -```php -$author = $book->author()->save( - new Author(['name' => 'John Doe']) -); - -// Similar -$author = - $book->author() - ->create(['name' => 'John Doe']); -``` - -You can update the embedded model using the `save` method (available since release 2.0.0): - -```php -$author = $book->author; - -$author->name = 'Jane Doe'; -$author->save(); -``` - -You can replace the embedded model with a new model like this: - -```php -$newAuthor = new Author(['name' => 'Jane Doe']); - -$book->author()->save($newAuthor); -``` - -Cross-Database Relationships ----------------------------- - -If you're using a hybrid MongoDB and SQL setup, you can define relationships across them. - -The model will automatically return a MongoDB-related or SQL-related relation based on the type of the related model. - -If you want this functionality to work both ways, your SQL-models will need to use the `MongoDB\Laravel\Eloquent\HybridRelations` trait. - -**This functionality only works for `hasOne`, `hasMany` and `belongsTo`.** - -The SQL model should use the `HybridRelations` trait: - -```php -use MongoDB\Laravel\Eloquent\HybridRelations; - -class User extends Model -{ - use HybridRelations; - - protected $connection = 'mysql'; - - public function messages() - { - return $this->hasMany(Message::class); - } -} -``` - -Within your MongoDB model, you should define the relationship: - -```php -use MongoDB\Laravel\Eloquent\Model; - -class Message extends Model -{ - protected $connection = 'mongodb'; - - public function user() - { - return $this->belongsTo(User::class); - } -} -``` - - diff --git a/docs/eloquent-models.txt b/docs/eloquent-models.txt new file mode 100644 index 000000000..af767a810 --- /dev/null +++ b/docs/eloquent-models.txt @@ -0,0 +1,522 @@ +.. _laravel-eloquent-models: + +=============== +Eloquent Models +=============== + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: php framework, odm, code example + +This package includes a MongoDB enabled Eloquent class that you can use to +define models for corresponding collections. + +Extending the base model +~~~~~~~~~~~~~~~~~~~~~~~~ + +To get started, create a new model class in your ``app\Models\`` directory. + +.. code-block:: php + + namespace App\Models; + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + // + } + +Just like a regular model, the MongoDB model class will know which collection +to use based on the model name. For ``Book``\ , the collection ``books`` will +be used. + +To change the collection, pass the ``$collection`` property: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $collection = 'my_books_collection'; + } + +.. note:: + + MongoDB documents are automatically stored with a unique ID that is stored + in the ``_id`` property. If you wish to use your own ID, substitute the + ``$primaryKey`` property and set it to your own primary key attribute name. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $primaryKey = 'id'; + } + + // MongoDB will also create _id, but the 'id' property will be used for primary key actions like find(). + Book::create(['id' => 1, 'title' => 'The Fault in Our Stars']); + +Likewise, you may define a ``connection`` property to override the name of the +database connection to reference the model. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + protected $connection = 'mongodb'; + } + +Soft Deletes +~~~~~~~~~~~~ + +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 delete for a model, apply the ``MongoDB\Laravel\Eloquent\SoftDeletes`` +Trait to the model: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\SoftDeletes; + + class User extends Model + { + use SoftDeletes; + } + +For more information check `Laravel Docs about Soft Deleting `__. + +Prunable +~~~~~~~~ + +``Prunable`` and ``MassPrunable`` traits are Laravel features to automatically +remove models from your database. You can use ``Illuminate\Database\Eloquent\Prunable`` +trait to remove models one by one. If you want to remove models in bulk, you +must use the ``MongoDB\Laravel\Eloquent\MassPrunable`` trait instead: it +will be more performant but can break links with other documents as it does +not load the models. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + use MongoDB\Laravel\Eloquent\MassPrunable; + + class Book extends Model + { + use MassPrunable; + } + +For more information check `Laravel Docs about Pruning Models `__. + +Dates +~~~~~ + +Eloquent allows you to work with Carbon or DateTime objects instead of MongoDate objects. Internally, these dates will be converted to MongoDate objects when saved to the database. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + protected $casts = ['birthday' => 'datetime']; + } + +This allows you to execute queries like this: + +.. code-block:: php + + $users = User::where( + 'birthday', '>', + new DateTime('-18 years') + )->get(); + +Extending the Authenticatable base model +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This package includes a MongoDB Authenticatable Eloquent class ``MongoDB\Laravel\Auth\User`` +that you can use to replace the default Authenticatable class ``Illuminate\Foundation\Auth\User`` +for your ``User`` model. + +.. code-block:: php + + use MongoDB\Laravel\Auth\User as Authenticatable; + + class User extends Authenticatable + { + + } + +Guarding attributes +~~~~~~~~~~~~~~~~~~~ + +When choosing between guarding attributes or marking some as fillable, Taylor +Otwell prefers the fillable route. This is in light of +`recent security issues described here `__. + +Keep in mind guarding still works, but you may experience unexpected behavior. + +Schema +------ + +The database driver also has (limited) schema builder support. You can +conveniently manipulate collections and set indexes. + +Basic Usage +~~~~~~~~~~~ + +.. code-block:: php + + Schema::create('users', function ($collection) { + $collection->index('name'); + $collection->unique('email'); + }); + +You can also pass all the parameters specified :manual:`in the MongoDB docs ` +to the ``$options`` parameter: + +.. code-block:: php + + Schema::create('users', function ($collection) { + $collection->index( + 'username', + null, + null, + [ + 'sparse' => true, + 'unique' => true, + 'background' => true, + ] + ); + }); + +Inherited operations: + + +* create and drop +* collection +* hasCollection +* index and dropIndex (compound indexes supported as well) +* unique + +MongoDB specific operations: + + +* background +* sparse +* expire +* geospatial + +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 `Laravel Docs `__ + +Geospatial indexes +~~~~~~~~~~~~~~~~~~ + +Geospatial indexes can improve query performance of location-based documents. + +They come in two forms: ``2d`` and ``2dsphere``. Use the schema builder to add +these to a collection. + +.. code-block:: php + + Schema::create('bars', function ($collection) { + $collection->geospatial('location', '2d'); + }); + +To add a ``2dsphere`` index: + +.. code-block:: php + + Schema::create('bars', function ($collection) { + $collection->geospatial('location', '2dsphere'); + }); + +Relationships +------------- + +Basic Usage +~~~~~~~~~~~ + +The only available relationships are: + + +* hasOne +* hasMany +* belongsTo +* belongsToMany + +The MongoDB-specific relationships are: + + +* embedsOne +* embedsMany + +Here is a small example: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function items() + { + return $this->hasMany(Item::class); + } + } + +The inverse relation of ``hasMany`` is ``belongsTo``: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Item extends Model + { + public function user() + { + return $this->belongsTo(User::class); + } + } + +belongsToMany and pivots +~~~~~~~~~~~~~~~~~~~~~~~~ + +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``: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function groups() + { + return $this->belongsToMany( + Group::class, null, 'user_ids', 'group_ids' + ); + } + } + +EmbedsMany Relationship +~~~~~~~~~~~~~~~~~~~~~~~ + +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. + +**REMEMBER**\ : These relations return Eloquent collections, they don't return +query builder objects! + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function books() + { + return $this->embedsMany(Book::class); + } + } + +You can access the embedded models through the dynamic property: + +.. code-block:: php + + $user = User::first(); + + foreach ($user->books as $book) { + // + } + +The inverse relation is auto\ *magically* available. You can omit the reverse +relation definition. + +.. code-block:: php + + $book = Book::first(); + + $user = $book->user; + +Inserting and updating embedded models works similar to the ``hasMany`` relation: + +.. code-block:: php + + $book = $user->books()->save( + new Book(['title' => 'A Game of Thrones']) + ); + + // or + $book = + $user->books() + ->create(['title' => 'A Game of Thrones']); + +You can update embedded models using their ``save`` method (available since +release 2.0.0): + +.. code-block:: php + + $book = $user->books()->first(); + + $book->title = 'A Game of Thrones'; + $book->save(); + +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): + +.. code-block:: php + + $book->delete(); + + // Similar operation + $user->books()->destroy($book); + +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: + +.. code-block:: php + + $user->books()->associate($book); + $user->save(); + +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: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class User extends Model + { + public function books() + { + return $this->embedsMany(Book::class, 'local_key'); + } + } + +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 `__ + +EmbedsOne Relationship +~~~~~~~~~~~~~~~~~~~~~~ + +The embedsOne relation is similar to the embedsMany relation, but only embeds a single model. + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Book extends Model + { + public function author() + { + return $this->embedsOne(Author::class); + } + } + +You can access the embedded models through the dynamic property: + +.. code-block:: php + + $book = Book::first(); + $author = $book->author; + +Inserting and updating embedded models works similar to the ``hasOne`` relation: + +.. code-block:: php + + $author = $book->author()->save( + new Author(['name' => 'John Doe']) + ); + + // Similar + $author = + $book->author() + ->create(['name' => 'John Doe']); + +You can update the embedded model using the ``save`` method (available since +release 2.0.0): + +.. code-block:: php + + $author = $book->author; + + $author->name = 'Jane Doe'; + $author->save(); + +You can replace the embedded model with a new model like this: + +.. code-block:: php + + $newAuthor = new Author(['name' => 'Jane Doe']); + + $book->author()->save($newAuthor); + +Cross-Database Relationships +---------------------------- + +If you're using a hybrid MongoDB and SQL setup, you can define relationships +across them. + +The model will automatically return a MongoDB-related or SQL-related relation +based on the type of the related model. + +If you want this functionality to work both ways, your SQL-models will need +to use the ``MongoDB\Laravel\Eloquent\HybridRelations`` trait. + +**This functionality only works for ``hasOne``\ , ``hasMany`` and ``belongsTo``.** + +The SQL model must use the ``HybridRelations`` trait: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\HybridRelations; + + class User extends Model + { + use HybridRelations; + + protected $connection = 'mysql'; + + public function messages() + { + return $this->hasMany(Message::class); + } + } + +Within your MongoDB model, you must define the following relationship: + +.. code-block:: php + + use MongoDB\Laravel\Eloquent\Model; + + class Message extends Model + { + protected $connection = 'mongodb'; + + public function user() + { + return $this->belongsTo(User::class); + } + } diff --git a/docs/index.txt b/docs/index.txt new file mode 100644 index 000000000..e58ba3532 --- /dev/null +++ b/docs/index.txt @@ -0,0 +1,70 @@ +=============== +Laravel MongoDB +=============== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: php framework, odm + +This package adds functionalities to the Eloquent model and Query builder for +MongoDB, using the original Laravel API. +*This library extends the original Laravel classes, so it uses exactly the +same methods.* + +This package was renamed to ``mongodb/laravel-mongodb`` because of a transfer +of ownership to MongoDB, Inc. It is compatible with Laravel 10.x. For older +versions of Laravel, please see the `old versions `__. + +- :ref:`laravel-install` +- :ref:`laravel-eloquent-models` +- :ref:`laravel-query-builder` +- :ref:`laravel-user-authentication` +- :ref:`laravel-queues` +- :ref:`laravel-transactions` +- :ref:`laravel-upgrading` + +Reporting Issues +---------------- + +Think you’ve found a bug in the library? Want to see a new feature? Please open a case in our issue management tool, JIRA: + +- `Create an account and login `__ +- Navigate to the `PHPORM `__ project. +- Click Create +- Please provide as much information as possible about the issue type and how to reproduce it. + +Note: All reported issues in JIRA project are public. + +For general questions and support requests, please use one of MongoDB's +:manual:`Technical Support ` channels. + +Security Vulnerabilities +~~~~~~~~~~~~~~~~~~~~~~~~ + +If you've identified a security vulnerability in a driver or any other MongoDB +project, please report it according to the instructions in +:manual:`Create a Vulnerability Report `. + + +Development +----------- + +Development is tracked in the `PHPORM `__ +project in MongoDB's JIRA. Documentation for contributing to this project may +be found in `CONTRIBUTING.md `__. + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /install + /eloquent-models + /query-builder + /user-authentication + /queues + /transactions + /upgrade + diff --git a/docs/install.md b/docs/install.md deleted file mode 100644 index d09628fec..000000000 --- a/docs/install.md +++ /dev/null @@ -1,64 +0,0 @@ -Getting Started -=============== - -Installation ------------- - -Make sure you have the MongoDB PHP driver installed. You can find installation instructions at https://php.net/manual/en/mongodb.installation.php - -Install the package via Composer: - -```bash -$ composer require mongodb/laravel-mongodb -``` - -In case your Laravel version does NOT autoload the packages, add the service provider to `config/app.php`: - -```php -'providers' => [ - // ... - MongoDB\Laravel\MongoDBServiceProvider::class, -], -``` - -Configuration -------------- - -To configure a new MongoDB connection, add a new connection entry to `config/database.php`: - -```php -'default' => env('DB_CONNECTION', 'mongodb'), - -'connections' => [ - 'mongodb' => [ - 'driver' => 'mongodb', - 'dsn' => env('DB_DSN'), - 'database' => env('DB_DATABASE', 'homestead'), - ], - // ... -], -``` - -The `dsn` key contains the connection string used to connect to your MongoDB deployment. The format and available options are documented in the [MongoDB documentation](https://docs.mongodb.com/manual/reference/connection-string/). - -Instead of using a connection string, you can also use the `host` and `port` configuration options to have the connection string created for you. - -```php -'connections' => [ - 'mongodb' => [ - 'driver' => 'mongodb', - 'host' => env('DB_HOST', '127.0.0.1'), - 'port' => env('DB_PORT', 27017), - 'database' => env('DB_DATABASE', 'homestead'), - 'username' => env('DB_USERNAME', 'homestead'), - 'password' => env('DB_PASSWORD', 'secret'), - 'options' => [ - 'appname' => 'homestead', - ], - ], -], -``` - -The `options` key in the connection configuration corresponds to the [`uriOptions` parameter](https://www.php.net/manual/en/mongodb-driver-manager.construct.php#mongodb-driver-manager.construct-urioptions). - -You are ready to [create your first MongoDB model](eloquent-models.md). diff --git a/docs/install.txt b/docs/install.txt new file mode 100644 index 000000000..795dbcff0 --- /dev/null +++ b/docs/install.txt @@ -0,0 +1,82 @@ +.. _laravel-install: + +=============== +Getting Started +=============== + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: php framework, odm, code example + +Installation +------------ + +Make sure you have the MongoDB PHP driver installed. You can find installation +instructions at `https://php.net/manual/en/mongodb.installation.php `__. + +Install the package by using Composer: + +.. code-block:: bash + + $ composer require mongodb/laravel-mongodb + +In case your Laravel version does NOT autoload the packages, add the service +provider to ``config/app.php``: + +.. code-block:: php + + 'providers' => [ + // ... + MongoDB\Laravel\MongoDBServiceProvider::class, + ], + +Configuration +------------- + +To configure a new MongoDB connection, add a new connection entry +to ``config/database.php``: + +.. code-block:: php + + 'default' => env('DB_CONNECTION', 'mongodb'), + + 'connections' => [ + 'mongodb' => [ + 'driver' => 'mongodb', + 'dsn' => env('DB_DSN'), + 'database' => env('DB_DATABASE', 'homestead'), + ], + // ... + ], + +The ``dsn`` key contains the connection string used to connect to your MongoDB +deployment. The format and available options are documented in the +:manual:`MongoDB documentation `. + +Instead of using a connection string, you can also use the ``host`` and +``port`` configuration options to have the connection string created for you. + +.. code-block:: php + + 'connections' => [ + 'mongodb' => [ + 'driver' => 'mongodb', + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', 27017), + 'database' => env('DB_DATABASE', 'homestead'), + 'username' => env('DB_USERNAME', 'homestead'), + 'password' => env('DB_PASSWORD', 'secret'), + 'options' => [ + 'appname' => 'homestead', + ], + ], + ], + +The ``options`` key in the connection configuration corresponds to the +`uriOptions `__ +parameter. + +You are ready to :ref:`create your first MongoDB model `. diff --git a/docs/query-builder.md b/docs/query-builder.md deleted file mode 100644 index 4438e889c..000000000 --- a/docs/query-builder.md +++ /dev/null @@ -1,602 +0,0 @@ -Query Builder -============= - -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. - -```php -$books = DB::collection('books')->get(); - -$hungerGames = - DB::collection('books') - ->where('name', 'Hunger Games') - ->first(); -``` - -If you are familiar with [Eloquent Queries](http://laravel.com/docs/queries), there is the same functionality. - -Available operations --------------------- - -**Retrieving all models** - -```php -$users = User::all(); -``` - -**Retrieving a record by primary key** - -```php -$user = User::find('517c43667db388101e00000f'); -``` - -**Where** - -```php -$posts = - Post::where('author.name', 'John') - ->take(10) - ->get(); -``` - -**OR Statements** - -```php -$posts = - Post::where('votes', '>', 0) - ->orWhere('is_approved', true) - ->get(); -``` - -**AND statements** - -```php -$users = - User::where('age', '>', 18) - ->where('name', '!=', 'John') - ->get(); -``` - -**NOT statements** - -```php -$users = User::whereNot('age', '>', 18)->get(); -``` - -**whereIn** - -```php -$users = User::whereIn('age', [16, 18, 20])->get(); -``` - -When using `whereNotIn` objects will be returned if the field is non-existent. Combine with `whereNotNull('age')` to leave out those documents. - -**whereBetween** - -```php -$posts = Post::whereBetween('votes', [1, 100])->get(); -``` - -**whereNull** - -```php -$users = User::whereNull('age')->get(); -``` - -**whereDate** - -```php -$users = User::whereDate('birthday', '2021-5-12')->get(); -``` - -The usage is the same as `whereMonth` / `whereDay` / `whereYear` / `whereTime` - -**Advanced wheres** - -```php -$users = - User::where('name', 'John') - ->orWhere(function ($query) { - return $query - ->where('votes', '>', 100) - ->where('title', '<>', 'Admin'); - })->get(); -``` - -**orderBy** - -```php -$users = User::orderBy('age', 'desc')->get(); -``` - -**Offset & Limit (skip & take)** - -```php -$users = - User::skip(10) - ->take(5) - ->get(); -``` - -**groupBy** - -Selected columns that are not grouped will be aggregated with the `$last` function. - -```php -$users = - Users::groupBy('title') - ->get(['title', 'name']); -``` - -**Distinct** - -Distinct requires a field for which to return the distinct values. - -```php -$users = User::distinct()->get(['name']); - -// Equivalent to: -$users = User::distinct('name')->get(); -``` - -Distinct can be combined with **where**: - -```php -$users = - User::where('active', true) - ->distinct('name') - ->get(); -``` - -**Like** - -```php -$spamComments = Comment::where('body', 'like', '%spam%')->get(); -``` - -**Aggregation** - -**Aggregations are only available for MongoDB versions greater than 2.2.x** - -```php -$total = Product::count(); -$price = Product::max('price'); -$price = Product::min('price'); -$price = Product::avg('price'); -$total = Product::sum('price'); -``` - -Aggregations can be combined with **where**: - -```php -$sold = Orders::where('sold', true)->sum('price'); -``` - -Aggregations can be also used on sub-documents: - -```php -$total = Order::max('suborder.price'); -``` - -**NOTE**: This aggregation only works with single sub-documents (like `EmbedsOne`) not subdocument arrays (like `EmbedsMany`). - -**Incrementing/Decrementing the value of a column** - -Perform increments or decrements (default 1) on specified attributes: - -```php -Cat::where('name', 'Kitty')->increment('age'); - -Car::where('name', 'Toyota')->decrement('weight', 50); -``` - -The number of updated objects is returned: - -```php -$count = User::increment('age'); -``` - -You may also specify additional columns to update: - -```php -Cat::where('age', 3) - ->increment('age', 1, ['group' => 'Kitty Club']); - -Car::where('weight', 300) - ->decrement('weight', 100, ['latest_change' => 'carbon fiber']); -``` - -### MongoDB-specific operators - -In addition to the Laravel Eloquent operators, all available MongoDB query operators can be used with `where`: - -```php -User::where($fieldName, $operator, $value)->get(); -``` - -It generates the following MongoDB filter: -```ts -{ $fieldName: { $operator: $value } } -``` - -**Exists** - -Matches documents that have the specified field. - -```php -User::where('age', 'exists', true)->get(); -``` - -**All** - -Matches arrays that contain all elements specified in the query. - -```php -User::where('roles', 'all', ['moderator', 'author'])->get(); -``` - -**Size** - -Selects documents if the array field is a specified size. - -```php -Post::where('tags', 'size', 3)->get(); -``` - -**Regex** - -Selects documents where values match a specified regular expression. - -```php -use MongoDB\BSON\Regex; - -User::where('name', 'regex', new Regex('.*doe', 'i'))->get(); -``` - -**NOTE:** you can also use the Laravel regexp operations. These will automatically convert your regular expression string to a `MongoDB\BSON\Regex` object. - -```php -User::where('name', 'regexp', '/.*doe/i')->get(); -``` - -The inverse of regexp: - -```php -User::where('name', 'not regexp', '/.*doe/i')->get(); -``` - -**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 - -```php -User::where('age', 'type', 2)->get(); -``` - -**Mod** - -Performs a modulo operation on the value of a field and selects documents with a specified result. - -```php -User::where('age', 'mod', [10, 0])->get(); -``` - -### MongoDB-specific Geo operations - -**Near** - -```php -$bars = Bar::where('location', 'near', [ - '$geometry' => [ - 'type' => 'Point', - 'coordinates' => [ - -0.1367563, // longitude - 51.5100913, // latitude - ], - ], - '$maxDistance' => 50, -])->get(); -``` - -**GeoWithin** - -```php -$bars = Bar::where('location', 'geoWithin', [ - '$geometry' => [ - 'type' => 'Polygon', - 'coordinates' => [ - [ - [-0.1450383, 51.5069158], - [-0.1367563, 51.5100913], - [-0.1270247, 51.5013233], - [-0.1450383, 51.5069158], - ], - ], - ], -])->get(); -``` - -**GeoIntersects** - -```php -$bars = Bar::where('location', 'geoIntersects', [ - '$geometry' => [ - 'type' => 'LineString', - 'coordinates' => [ - [-0.144044, 51.515215], - [-0.129545, 51.507864], - ], - ], -])->get(); -``` - -**GeoNear** - -You are able to make a `geoNear` query on mongoDB. -You don't need to specify the automatic fields on the model. -The returned instance is a collection. So you're able to make the [Collection](https://laravel.com/docs/9.x/collections) operations. -Just make sure that your model has a `location` field, and a [2ndSphereIndex](https://www.mongodb.com/docs/manual/core/2dsphere). -The data in the `location` field must be saved as [GeoJSON](https://www.mongodb.com/docs/manual/reference/geojson/). -The `location` points must be saved as [WGS84](https://www.mongodb.com/docs/manual/reference/glossary/#std-term-WGS84) reference system for geometry calculation. That means, basically, you need to save `longitude and latitude`, in that order specifically, and to find near with calculated distance, you `need to do the same way`. - -``` -Bar::find("63a0cd574d08564f330ceae2")->update( - [ - 'location' => [ - 'type' => 'Point', - 'coordinates' => [ - -0.1367563, - 51.5100913 - ] - ] - ] -); -$bars = Bar::raw(function ($collection) { - return $collection->aggregate([ - [ - '$geoNear' => [ - "near" => [ "type" => "Point", "coordinates" => [-0.132239, 51.511874] ], - "distanceField" => "dist.calculated", - "minDistance" => 0, - "maxDistance" => 6000, - "includeLocs" => "dist.location", - "spherical" => true, - ] - ] - ]); -}); -``` - -### Inserts, updates and deletes - -Inserting, updating and deleting records works just like the original Eloquent. Please check [Laravel Docs' Eloquent section](https://laravel.com/docs/6.x/eloquent). - -Here, only the MongoDB-specific operations are specified. - -### MongoDB specific operations - -**Raw Expressions** - -These expressions will be injected directly into the query. - -```php -User::whereRaw([ - 'age' => ['$gt' => 30, '$lt' => 40], -])->get(); - -User::whereRaw([ - '$where' => '/.*123.*/.test(this.field)', -])->get(); - -User::whereRaw([ - '$where' => '/.*123.*/.test(this["hyphenated-field"])', -])->get(); -``` - -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. - -**Cursor timeout** - -To prevent `MongoCursorTimeout` exceptions, you can manually set a timeout value that will be applied to the cursor: - -```php -DB::collection('users')->timeout(-1)->get(); -``` - -**Upsert** - -Update or insert a document. Additional options for the update method are passed directly to the native update method. - -```php -// Query Builder -DB::collection('users') - ->where('name', 'John') - ->update($data, ['upsert' => true]); - -// Eloquent -$user->update($data, ['upsert' => true]); -``` - -**Projections** - -You can apply projections to your queries using the `project` method. - -```php -DB::collection('items') - ->project(['tags' => ['$slice' => 1]]) - ->get(); - -DB::collection('items') - ->project(['tags' => ['$slice' => [3, 7]]]) - ->get(); -``` - -**Projections with Pagination** - -```php -$limit = 25; -$projections = ['id', 'name']; - -DB::collection('items') - ->paginate($limit, $projections); -``` - -**Push** - -Add one or multiple values to the `items` array. - -```php -// Push the value to the matched documents -DB::collection('users') - ->where('name', 'John') - // Push a single value to the items array - ->push('items', 'boots'); -// Result: -// items: ['boots'] - -DB::collection('users') - ->where('name', 'John') - // Push multiple values to the items array - ->push('items', ['hat', 'jeans']); -// Result: -// items: ['boots', 'hat', 'jeans'] - -// Or - -// Push the values directly to a model object -$user->push('items', 'boots'); -$user->push('items', ['hat', 'jeans']); -``` - -To add embedded document or array values to the `messages` array, those values must be specified within a list array. - -```php -DB::collection('users') - ->where('name', 'John') - // Push an embedded document as a value to the messages array - ->push('messages', [ - [ 'from' => 'Jane Doe', 'message' => 'Hi John' ] - ]); -// Result: -// messages: [ -// { from: "Jane Doe", message: "Hi John" } -// ] - -// Or - -$user->push('messages', [ - [ 'from' => 'Jane Doe', 'message' => 'Hi John' ] -]); -``` - -If you **DON'T** want duplicate values, set the third parameter to `true`: - -```php -DB::collection('users') - ->where('name', 'John') - ->push('items', 'boots'); -// Result: -// items: ['boots'] - -DB::collection('users') - ->where('name', 'John') - ->push('items', ['hat', 'boots', 'jeans'], true); -// Result: -// items: ['boots', 'hat', 'jeans'] - -// Or - -$user->push('messages', [ - [ 'from' => 'Jane Doe', 'message' => 'Hi John' ] -]); -// Result: -// messages: [ -// { from: "Jane Doe", message: "Hi John" } -// ] - -$user->push('messages', [ - [ 'from' => 'Jess Doe', 'message' => 'Hi' ], - [ 'from' => 'Jane Doe', 'message' => 'Hi John' ], -], true); -// Result: -// messages: [ -// { from: "Jane Doe", message: "Hi John" } -// { from: "Jess Doe", message: "Hi" } -// ] -``` - -**Pull** - -Remove one or multiple values from the `items` array. - -```php -// items: ['boots', 'hat', 'jeans'] - -DB::collection('users') - ->where('name', 'John') - ->pull('items', 'boots'); // Pull a single value -// Result: -// items: ['hat', 'jeans'] - -// Or pull multiple values - -$user->pull('items', ['boots', 'jeans']); -// Result: -// items: ['hat'] -``` - -Embedded document and arrays values can also be removed from the `messages` array. - -```php -// Latest state: -// messages: [ -// { from: "Jane Doe", message: "Hi John" } -// { from: "Jess Doe", message: "Hi" } -// ] - -DB::collection('users') - ->where('name', 'John') - // Pull an embedded document from the array - ->pull('messages', [ - [ 'from' => 'Jane Doe', 'message' => 'Hi John' ] - ]); -// Result: -// messages: [ -// { from: "Jess Doe", message: "Hi" } -// ] - -// Or pull multiple embedded documents - -$user->pull('messages', [ - [ 'from' => 'Jane Doe', 'message' => 'Hi John' ], - [ 'from' => 'Jess Doe', 'message' => 'Hi' ] -]); -// Result: -// messages: [ ] -``` - -**Unset** - -Remove one or more fields from a document. - -```php -DB::collection('users') - ->where('name', 'John') - ->unset('note'); - -$user->unset('note'); - -$user->save(); -``` - -Using the native `unset` on models will work as well: - -```php -unset($user['note']); -unset($user->node); -``` diff --git a/docs/query-builder.txt b/docs/query-builder.txt new file mode 100644 index 000000000..267285a66 --- /dev/null +++ b/docs/query-builder.txt @@ -0,0 +1,569 @@ +.. _laravel-query-builder: + +============= +Query Builder +============= + +.. facet:: + + :name: genre + :values: tutorial + +.. meta:: + :keywords: php framework, odm, code example + +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`` and +other MongoDB specific operators/operations. + +.. code-block:: php + + $books = DB::collection('books')->get(); + + $hungerGames = + DB::collection('books') + ->where('name', 'Hunger Games') + ->first(); + +If you are familiar with `Eloquent Queries `__, +there is the same functionality. + +Available operations +-------------------- + +**Retrieving all models** + +.. code-block:: php + + $users = User::all(); + +**Retrieving a record by primary key** + +.. code-block:: php + + $user = User::find('517c43667db388101e00000f'); + +**Where** + +.. code-block:: php + + $posts = + Post::where('author.name', 'John') + ->take(10) + ->get(); + +**OR Statements** + +.. code-block:: php + + $posts = + Post::where('votes', '>', 0) + ->orWhere('is_approved', true) + ->get(); + +**AND statements** + +.. code-block:: php + + $users = + User::where('age', '>', 18) + ->where('name', '!=', 'John') + ->get(); + +**NOT statements** + +.. code-block:: php + + $users = User::whereNot('age', '>', 18)->get(); + +**whereIn** + +.. code-block:: php + + $users = User::whereIn('age', [16, 18, 20])->get(); + +When using ``whereNotIn`` objects will be returned if the field is +non-existent. Combine with ``whereNotNull('age')`` to omit those documents. + +**whereBetween** + +.. code-block:: php + + $posts = Post::whereBetween('votes', [1, 100])->get(); + +**whereNull** + +.. code-block:: php + + $users = User::whereNull('age')->get(); + +**whereDate** + +.. code-block:: php + + $users = User::whereDate('birthday', '2021-5-12')->get(); + +The usage is the same as ``whereMonth`` / ``whereDay`` / ``whereYear`` / ``whereTime`` + +**Advanced wheres** + +.. code-block:: php + + $users = + User::where('name', 'John') + ->orWhere(function ($query) { + return $query + ->where('votes', '>', 100) + ->where('title', '<>', 'Admin'); + })->get(); + +**orderBy** + +.. code-block:: php + + $users = User::orderBy('age', 'desc')->get(); + +**Offset & Limit (skip & take)** + +.. code-block:: php + + $users = + User::skip(10) + ->take(5) + ->get(); + +**groupBy** + +Selected columns that are not grouped will be aggregated with the ``$last`` +function. + +.. code-block:: php + + $users = + Users::groupBy('title') + ->get(['title', 'name']); + +**Distinct** + +Distinct requires a field for which to return the distinct values. + +.. code-block:: php + + $users = User::distinct()->get(['name']); + + // Equivalent to: + $users = User::distinct('name')->get(); + +Distinct can be combined with **where**\ : + +.. code-block:: php + + $users = + User::where('active', true) + ->distinct('name') + ->get(); + +**Like** + +.. code-block:: php + + $spamComments = Comment::where('body', 'like', '%spam%')->get(); + +**Aggregation** + +**Aggregations are only available for MongoDB versions greater than 2.2.x** + +.. code-block:: php + + $total = Product::count(); + $price = Product::max('price'); + $price = Product::min('price'); + $price = Product::avg('price'); + $total = Product::sum('price'); + +Aggregations can be combined with **where**\ : + +.. code-block:: php + + $sold = Orders::where('sold', true)->sum('price'); + +Aggregations can be also used on sub-documents: + +.. code-block:: php + + $total = Order::max('suborder.price'); + +.. note:: + + This aggregation only works with single sub-documents (like ``EmbedsOne``) + not subdocument arrays (like ``EmbedsMany``). + +**Incrementing/Decrementing the value of a column** + +Perform increments or decrements (default 1) on specified attributes: + +.. code-block:: php + + Cat::where('name', 'Kitty')->increment('age'); + + Car::where('name', 'Toyota')->decrement('weight', 50); + +The number of updated objects is returned: + +.. code-block:: php + + $count = User::increment('age'); + +You may also specify more columns to update: + +.. code-block:: php + + Cat::where('age', 3) + ->increment('age', 1, ['group' => 'Kitty Club']); + + Car::where('weight', 300) + ->decrement('weight', 100, ['latest_change' => 'carbon fiber']); + +MongoDB-specific operators +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the Laravel Eloquent operators, all available MongoDB query +operators can be used with ``where``: + +.. code-block:: php + + User::where($fieldName, $operator, $value)->get(); + +It generates the following MongoDB filter: + +.. code-block:: ts + + { $fieldName: { $operator: $value } } + +**Exists** + +Matches documents that have the specified field. + +.. code-block:: php + + User::where('age', 'exists', true)->get(); + +**All** + +Matches arrays that contain all elements specified in the query. + +.. code-block:: php + + User::where('roles', 'all', ['moderator', 'author'])->get(); + +**Size** + +Selects documents if the array field is a specified size. + +.. code-block:: php + + Post::where('tags', 'size', 3)->get(); + +**Regex** + +Selects documents where values match a specified regular expression. + +.. code-block:: php + + use MongoDB\BSON\Regex; + + User::where('name', 'regex', new Regex('.*doe', 'i'))->get(); + +.. note:: + + You can also use the Laravel regexp operations. These will automatically + convert your regular expression string to a ``MongoDB\BSON\Regex`` object. + +.. code-block:: php + + User::where('name', 'regexp', '/.*doe/i')->get(); + +The inverse of regexp: + +.. code-block:: php + + User::where('name', 'not regexp', '/.*doe/i')->get(); + +**Type** + +Selects documents if a field is of the specified type. For more information +check: :manual:`$type ` in the +MongoDB Server documentation. + +.. code-block:: php + + User::where('age', 'type', 2)->get(); + +**Mod** + +Performs a modulo operation on the value of a field and selects documents with +a specified result. + +.. code-block:: php + + User::where('age', 'mod', [10, 0])->get(); + +MongoDB-specific Geo operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Near** + +.. code-block:: php + + $bars = Bar::where('location', 'near', [ + '$geometry' => [ + 'type' => 'Point', + 'coordinates' => [ + -0.1367563, // longitude + 51.5100913, // latitude + ], + ], + '$maxDistance' => 50, + ])->get(); + +**GeoWithin** + +.. code-block:: php + + $bars = Bar::where('location', 'geoWithin', [ + '$geometry' => [ + 'type' => 'Polygon', + 'coordinates' => [ + [ + [-0.1450383, 51.5069158], + [-0.1367563, 51.5100913], + [-0.1270247, 51.5013233], + [-0.1450383, 51.5069158], + ], + ], + ], + ])->get(); + +**GeoIntersects** + +.. code-block:: php + + $bars = Bar::where('location', 'geoIntersects', [ + '$geometry' => [ + 'type' => 'LineString', + 'coordinates' => [ + [-0.144044, 51.515215], + [-0.129545, 51.507864], + ], + ], + ])->get(); + +**GeoNear** + +You can make a ``geoNear`` query on MongoDB. +You can omit specifying the automatic fields on the model. +The returned instance is a collection, so you can call the `Collection `__ operations. +Make sure that your model has a ``location`` field, and a +`2ndSphereIndex `__. +The data in the ``location`` field must be saved as `GeoJSON `__. +The ``location`` points must be saved as `WGS84 `__ +reference system for geometry calculation. That means that you must +save ``longitude and latitude``, in that order specifically, and to find near +with calculated distance, you ``must do the same way``. + +.. code-block:: + + Bar::find("63a0cd574d08564f330ceae2")->update( + [ + 'location' => [ + 'type' => 'Point', + 'coordinates' => [ + -0.1367563, + 51.5100913 + ] + ] + ] + ); + $bars = Bar::raw(function ($collection) { + return $collection->aggregate([ + [ + '$geoNear' => [ + "near" => [ "type" => "Point", "coordinates" => [-0.132239, 51.511874] ], + "distanceField" => "dist.calculated", + "minDistance" => 0, + "maxDistance" => 6000, + "includeLocs" => "dist.location", + "spherical" => true, + ] + ] + ]); + }); + +Inserts, updates and deletes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Inserting, updating and deleting records works just like the original Eloquent. +Please check `Laravel Docs' Eloquent section `__. + +Here, only the MongoDB-specific operations are specified. + +MongoDB specific operations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Raw Expressions** + +These expressions will be injected directly into the query. + +.. code-block:: php + + User::whereRaw([ + 'age' => ['$gt' => 30, '$lt' => 40], + ])->get(); + + User::whereRaw([ + '$where' => '/.*123.*/.test(this.field)', + ])->get(); + + User::whereRaw([ + '$where' => '/.*123.*/.test(this["hyphenated-field"])', + ])->get(); + +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. + +**Cursor timeout** + +To prevent ``MongoCursorTimeout`` exceptions, you can manually set a timeout +value that will be applied to the cursor: + +.. code-block:: php + + DB::collection('users')->timeout(-1)->get(); + +**Upsert** + +Update or insert a document. Other options for the update method can be +passed directly to the native update method. + +.. code-block:: php + + // Query Builder + DB::collection('users') + ->where('name', 'John') + ->update($data, ['upsert' => true]); + + // Eloquent + $user->update($data, ['upsert' => true]); + +**Projections** + +You can apply projections to your queries using the ``project`` method. + +.. code-block:: php + + DB::collection('items') + ->project(['tags' => ['$slice' => 1]]) + ->get(); + + DB::collection('items') + ->project(['tags' => ['$slice' => [3, 7]]]) + ->get(); + +**Projections with Pagination** + +.. code-block:: php + + $limit = 25; + $projections = ['id', 'name']; + + DB::collection('items') + ->paginate($limit, $projections); + +**Push** + +Add items to an array. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('items', 'boots'); + + $user->push('items', 'boots'); + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + + $user->push('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + +If you **DON'T** want duplicate items, set the third parameter to ``true``\ : + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->push('items', 'boots', true); + + $user->push('items', 'boots', true); + +**Pull** + +Remove an item from an array. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->pull('items', 'boots'); + + $user->pull('items', 'boots'); + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->pull('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + + $user->pull('messages', [ + 'from' => 'Jane Doe', + 'message' => 'Hi John', + ]); + +**Unset** + +Remove one or more fields from a document. + +.. code-block:: php + + DB::collection('users') + ->where('name', 'John') + ->unset('note'); + + $user->unset('note'); + + $user->save(); + +Using the native ``unset`` on models will work as well: + +.. code-block:: php + + unset($user['note']); + unset($user->node); diff --git a/docs/queues.md b/docs/queues.md deleted file mode 100644 index 0645a3d9e..000000000 --- a/docs/queues.md +++ /dev/null @@ -1,34 +0,0 @@ -Queues -====== - -If you want to use MongoDB as your database backend for Laravel Queue, change the driver in `config/queue.php`: - -```php -'connections' => [ - 'database' => [ - 'driver' => 'mongodb', - // You can also specify your jobs specific database created on config/database.php - 'connection' => 'mongodb-job', - 'table' => 'jobs', - 'queue' => 'default', - 'expire' => 60, - ], -], -``` - -If you want to use MongoDB to handle failed jobs, change the database in `config/queue.php`: - -```php -'failed' => [ - 'driver' => 'mongodb', - // You can also specify your jobs specific database created on config/database.php - 'database' => 'mongodb-job', - 'table' => 'failed_jobs', -], -``` - -Add the service provider in `config/app.php`: - -```php -MongoDB\Laravel\MongoDBQueueServiceProvider::class, -``` diff --git a/docs/queues.txt b/docs/queues.txt new file mode 100644 index 000000000..330662913 --- /dev/null +++ b/docs/queues.txt @@ -0,0 +1,46 @@ +.. _laravel-queues: + +====== +Queues +====== + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: php framework, odm, code example + +If you want to use MongoDB as your database backend for Laravel Queue, change +the driver in ``config/queue.php``: + +.. code-block:: php + + 'connections' => [ + 'database' => [ + 'driver' => 'mongodb', + // You can also specify your jobs specific database created on config/database.php + 'connection' => 'mongodb-job', + 'table' => 'jobs', + 'queue' => 'default', + 'expire' => 60, + ], + ], + +If you want to use MongoDB to handle failed jobs, change the database in +``config/queue.php``: + +.. code-block:: php + + 'failed' => [ + 'driver' => 'mongodb', + // You can also specify your jobs specific database created on config/database.php + 'database' => 'mongodb-job', + 'table' => 'failed_jobs', + ], + +Add the service provider in ``config/app.php``: + +.. code-block:: php + + MongoDB\Laravel\MongoDBQueueServiceProvider::class, diff --git a/docs/transactions.md b/docs/transactions.md deleted file mode 100644 index fad0df803..000000000 --- a/docs/transactions.md +++ /dev/null @@ -1,56 +0,0 @@ -Transactions -============ - -Transactions require MongoDB version ^4.0 as well as deployment of replica set or sharded clusters. You can find more information [in the MongoDB docs](https://docs.mongodb.com/manual/core/transactions/) - -```php -DB::transaction(function () { - User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); - DB::collection('users')->where('name', 'john')->update(['age' => 20]); - DB::collection('users')->where('name', 'john')->delete(); -}); -``` - -```php -// begin a transaction -DB::beginTransaction(); -User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); -DB::collection('users')->where('name', 'john')->update(['age' => 20]); -DB::collection('users')->where('name', 'john')->delete(); - -// commit changes -DB::commit(); -``` - -To abort a transaction, call the `rollBack` method at any point during the transaction: - -```php -DB::beginTransaction(); -User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); - -// Abort the transaction, discarding any data created as part of it -DB::rollBack(); -``` - -**NOTE:** Transactions in MongoDB cannot be nested. DB::beginTransaction() function will start new transactions in a new created or existing session and will raise the RuntimeException when transactions already exist. See more in MongoDB official docs [Transactions and Sessions](https://www.mongodb.com/docs/manual/core/transactions/#transactions-and-sessions) - -```php -DB::beginTransaction(); -User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']); - -// This call to start a nested transaction will raise a RuntimeException -DB::beginTransaction(); -DB::collection('users')->where('name', 'john')->update(['age' => 20]); -DB::commit(); -DB::rollBack(); -``` - -Database Testing ----------------- - -For testing, the traits `Illuminate\Foundation\Testing\DatabaseTransactions` and `Illuminate\Foundation\Testing\RefreshDatabase` are not yet supported. -Instead, create migrations and use the `DatabaseMigrations` trait to reset the database after each test: - -```php -use Illuminate\Foundation\Testing\DatabaseMigrations; -``` diff --git a/docs/transactions.txt b/docs/transactions.txt new file mode 100644 index 000000000..ee70f8c8b --- /dev/null +++ b/docs/transactions.txt @@ -0,0 +1,79 @@ +.. _laravel-transactions: + +============ +Transactions +============ + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: php framework, odm, code example + +MongoDB transactions require the following software and topology: + +- MongoDB version 4.0 or later +- A replica set deployment or sharded cluster + +You can find more information :manual:`in the MongoDB docs ` + +.. code-block:: php + + DB::transaction(function () { + User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::collection('users')->where('name', 'john')->delete(); + }); + +.. code-block:: php + + // begin a transaction + DB::beginTransaction(); + User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::collection('users')->where('name', 'john')->delete(); + + // commit changes + DB::commit(); + +To abort a transaction, call the ``rollBack`` method at any point during the transaction: + +.. code-block:: php + + DB::beginTransaction(); + User::create(['name' => 'john', 'age' => 19, 'title' => 'admin', 'email' => 'john@example.com']); + + // Abort the transaction, discarding any data created as part of it + DB::rollBack(); + + +.. note:: + + Transactions in MongoDB cannot be nested. DB::beginTransaction() function + will start new transactions in a new created or existing session and will + raise the RuntimeException when transactions already exist. See more in + MongoDB official docs :manual:`Transactions and Sessions `. + +.. code-block:: php + + DB::beginTransaction(); + User::create(['name' => 'john', 'age' => 20, 'title' => 'admin']); + + // This call to start a nested transaction will raise a RuntimeException + DB::beginTransaction(); + DB::collection('users')->where('name', 'john')->update(['age' => 20]); + DB::commit(); + DB::rollBack(); + +Database Testing +---------------- + +For testing, the traits ``Illuminate\Foundation\Testing\DatabaseTransactions`` +and ``Illuminate\Foundation\Testing\RefreshDatabase`` are not yet supported. +Instead, create migrations and use the ``DatabaseMigrations`` trait to reset +the database after each test: + +.. code-block:: php + + use Illuminate\Foundation\Testing\DatabaseMigrations; diff --git a/docs/upgrade.md b/docs/upgrade.md deleted file mode 100644 index 612dd27af..000000000 --- a/docs/upgrade.md +++ /dev/null @@ -1,19 +0,0 @@ -Upgrading -========= - -The PHP library uses [semantic versioning](https://semver.org/). Upgrading to a new major version may require changes to your application. - -Upgrading from version 3 to 4 ------------------------------ - -- Laravel 10.x is required -- Change dependency name in your composer.json to `"mongodb/laravel-mongodb": "^4.0"` and run `composer update` -- Change namespace from `Jenssegers\Mongodb\` to `MongoDB\Laravel\` in your models and config -- Remove support for non-Laravel projects -- Replace `$dates` with `$casts` in your models -- Call `$model->save()` after `$model->unset('field')` to persist the change -- Replace calls to `Query\Builder::whereAll($column, $values)` with `Query\Builder::where($column, 'all', $values)` -- `Query\Builder::delete()` doesn't accept `limit()` other than `1` or `null`. -- `whereDate`, `whereDay`, `whereMonth`, `whereYear`, `whereTime` now use MongoDB operators on date fields -- Replace `Illuminate\Database\Eloquent\MassPrunable` with `MongoDB\Laravel\Eloquent\MassPrunable` in your models -- Remove calls to not-supported methods of `Query\Builder`: `toSql`, `toRawSql`, `whereColumn`, `whereFullText`, `groupByRaw`, `orderByRaw`, `unionAll`, `union`, `having`, `havingRaw`, `havingBetween`, `whereIntegerInRaw`, `orWhereIntegerInRaw`, `whereIntegerNotInRaw`, `orWhereIntegerNotInRaw`. diff --git a/docs/upgrade.txt b/docs/upgrade.txt new file mode 100644 index 000000000..8148fbdfc --- /dev/null +++ b/docs/upgrade.txt @@ -0,0 +1,49 @@ +.. _laravel-upgrading: + +========= +Upgrading +========= + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: php framework, odm, code example + +The PHP library uses `semantic versioning `__. Upgrading +to a new major version may require changes to your application. + +Upgrading from version 3 to 4 +----------------------------- + +- Laravel 10.x is required + +- Change dependency name in your composer.json to ``"mongodb/laravel-mongodb": "^4.0"`` + and run ``composer update`` + +- Change namespace from ``Jenssegers\Mongodb\`` to ``MongoDB\Laravel\`` + in your models and config + +- Remove support for non-Laravel projects + +- Replace ``$dates`` with ``$casts`` in your models + +- Call ``$model->save()`` after ``$model->unset('field')`` to persist the change + +- Replace calls to ``Query\Builder::whereAll($column, $values)`` with + ``Query\Builder::where($column, 'all', $values)`` + +- ``Query\Builder::delete()`` doesn't accept ``limit()`` other than ``1`` or ``null``. + +- ``whereDate``, ``whereDay``, ``whereMonth``, ``whereYear``, ``whereTime`` + now use MongoDB operators on date fields + +- Replace ``Illuminate\Database\Eloquent\MassPrunable`` with ``MongoDB\Laravel\Eloquent\MassPrunable`` + in your models + +- Remove calls to not-supported methods of ``Query\Builder``: ``toSql``, + ``toRawSql``, ``whereColumn``, ``whereFullText``, ``groupByRaw``, + ``orderByRaw``, ``unionAll``, ``union``, ``having``, ``havingRaw``, + ``havingBetween``, ``whereIntegerInRaw``, ``orWhereIntegerInRaw``, + ``whereIntegerNotInRaw``, ``orWhereIntegerNotInRaw``. diff --git a/docs/user-authentication.md b/docs/user-authentication.md deleted file mode 100644 index 72341ceae..000000000 --- a/docs/user-authentication.md +++ /dev/null @@ -1,15 +0,0 @@ -User authentication -================== - -If you want to use Laravel's native Auth functionality, register this included service provider: - -```php -MongoDB\Laravel\Auth\PasswordResetServiceProvider::class, -``` - -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. - - - diff --git a/docs/user-authentication.txt b/docs/user-authentication.txt new file mode 100644 index 000000000..8755c7c6a --- /dev/null +++ b/docs/user-authentication.txt @@ -0,0 +1,24 @@ +.. _laravel-user-authentication: + +=================== +User authentication +=================== + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: php framework, odm, code example + +If you want to use Laravel's native Auth functionality, register this included +service provider: + +.. code-block:: php + + MongoDB\Laravel\Auth\PasswordResetServiceProvider::class, + +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 can omit this service provider. From ed5911640751e3a4c559c66beab1ffeb25eee918 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Tue, 9 Jan 2024 14:52:50 -0500 Subject: [PATCH 2/3] Updated changelog and readme. RST fixes --- CHANGELOG.md | 2 ++ README.md | 14 +++++++------- docs/eloquent-models.txt | 8 ++++---- docs/query-builder.txt | 7 +++---- docs/upgrade.txt | 2 +- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66690e932..8e4d01e25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog All notable changes to this project will be documented in this file. +* Move documentation to the mongodb.com domain at [https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/) + ## [4.1.0] - 2023-12-14 * PHPORM-100 Support query on numerical field names by [@GromNaN](https://github.com/GromNaN) in [#2642](https://github.com/mongodb/laravel-mongodb/pull/2642) diff --git a/README.md b/README.md index 60a48f725..71074ee62 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ This package was renamed to `mongodb/laravel-mongodb` because of a transfer of o It is compatible with Laravel 10.x. For older versions of Laravel, please refer to the [old versions](https://github.com/mongodb/laravel-mongodb/tree/3.9#laravel-version-compatibility). -- [Installation](docs/install.md) -- [Eloquent Models](docs/eloquent-models.md) -- [Query Builder](docs/query-builder.md) -- [Transactions](docs/transactions.md) -- [User Authentication](docs/user-authentication.md) -- [Queues](docs/queues.md) -- [Upgrading](docs/upgrade.md) +- [Installation](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/install/) +- [Eloquent Models](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/eloquent-models/) +- [Query Builder](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/query-builder/) +- [Transactions](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/transactions/) +- [User Authentication](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/user-authentication/) +- [Queues](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/queues/) +- [Upgrading](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/upgrade/) ## Reporting Issues diff --git a/docs/eloquent-models.txt b/docs/eloquent-models.txt index af767a810..04acaff86 100644 --- a/docs/eloquent-models.txt +++ b/docs/eloquent-models.txt @@ -17,7 +17,7 @@ define models for corresponding collections. Extending the base model ~~~~~~~~~~~~~~~~~~~~~~~~ -To get started, create a new model class in your ``app\Models\`` directory. +To get started, create a new model class in your ``app\Models\\`` directory. .. code-block:: php @@ -31,7 +31,7 @@ To get started, create a new model class in your ``app\Models\`` directory. } Just like a regular model, the MongoDB model class will know which collection -to use based on the model name. For ``Book``\ , the collection ``books`` will +to use based on the model name. For ``Book``, the collection ``books`` will be used. To change the collection, pass the ``$collection`` property: @@ -346,7 +346,7 @@ You can access the embedded models through the dynamic property: // } -The inverse relation is auto\ *magically* available. You can omit the reverse +The inverse relation is auto *magically* available. You can omit the reverse relation definition. .. code-block:: php @@ -485,7 +485,7 @@ based on the type of the related model. If you want this functionality to work both ways, your SQL-models will need to use the ``MongoDB\Laravel\Eloquent\HybridRelations`` trait. -**This functionality only works for ``hasOne``\ , ``hasMany`` and ``belongsTo``.** +**This functionality only works for ``hasOne``, ``hasMany`` and ``belongsTo``.** The SQL model must use the ``HybridRelations`` trait: diff --git a/docs/query-builder.txt b/docs/query-builder.txt index 267285a66..40d2b9634 100644 --- a/docs/query-builder.txt +++ b/docs/query-builder.txt @@ -5,7 +5,6 @@ Query Builder ============= .. facet:: - :name: genre :values: tutorial @@ -158,7 +157,7 @@ Distinct requires a field for which to return the distinct values. // Equivalent to: $users = User::distinct('name')->get(); -Distinct can be combined with **where**\ : +Distinct can be combined with **where**: .. code-block:: php @@ -185,7 +184,7 @@ Distinct can be combined with **where**\ : $price = Product::avg('price'); $total = Product::sum('price'); -Aggregations can be combined with **where**\ : +Aggregations can be combined with **where**: .. code-block:: php @@ -511,7 +510,7 @@ Add items to an array. 'message' => 'Hi John', ]); -If you **DON'T** want duplicate items, set the third parameter to ``true``\ : +If you **DON'T** want duplicate items, set the third parameter to ``true``: .. code-block:: php diff --git a/docs/upgrade.txt b/docs/upgrade.txt index 8148fbdfc..55fae039a 100644 --- a/docs/upgrade.txt +++ b/docs/upgrade.txt @@ -22,7 +22,7 @@ Upgrading from version 3 to 4 - Change dependency name in your composer.json to ``"mongodb/laravel-mongodb": "^4.0"`` and run ``composer update`` -- Change namespace from ``Jenssegers\Mongodb\`` to ``MongoDB\Laravel\`` +- Change namespace from ``Jenssegers\Mongodb\\`` to ``MongoDB\Laravel\\`` in your models and config - Remove support for non-Laravel projects From 8462c8e0b97c656a7d3834b5dc1150149ce626ec Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Wed, 10 Jan 2024 13:32:27 -0500 Subject: [PATCH 3/3] backslash-backtick fixes --- docs/eloquent-models.txt | 2 +- docs/upgrade.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/eloquent-models.txt b/docs/eloquent-models.txt index 04acaff86..d10822c37 100644 --- a/docs/eloquent-models.txt +++ b/docs/eloquent-models.txt @@ -17,7 +17,7 @@ define models for corresponding collections. Extending the base model ~~~~~~~~~~~~~~~~~~~~~~~~ -To get started, create a new model class in your ``app\Models\\`` directory. +To get started, create a new model class in your ``app\Models\`` directory. .. code-block:: php diff --git a/docs/upgrade.txt b/docs/upgrade.txt index 55fae039a..8148fbdfc 100644 --- a/docs/upgrade.txt +++ b/docs/upgrade.txt @@ -22,7 +22,7 @@ Upgrading from version 3 to 4 - Change dependency name in your composer.json to ``"mongodb/laravel-mongodb": "^4.0"`` and run ``composer update`` -- Change namespace from ``Jenssegers\Mongodb\\`` to ``MongoDB\Laravel\\`` +- Change namespace from ``Jenssegers\Mongodb\`` to ``MongoDB\Laravel\`` in your models and config - Remove support for non-Laravel projects