From 8fbbcc44b6b43bb47a1d3f2261649a4c8b08e0a0 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Wed, 27 Mar 2024 17:15:51 -0400 Subject: [PATCH 01/26] DOCSP-35948: Write operations --- docs/fundamentals.txt | 27 +++++++++++++++++++ .../read-operations.txt} | 1 + docs/index.txt | 5 ++-- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 docs/fundamentals.txt rename docs/{retrieve.txt => fundamentals/read-operations.txt} (99%) diff --git a/docs/fundamentals.txt b/docs/fundamentals.txt new file mode 100644 index 000000000..6e2fa2c7f --- /dev/null +++ b/docs/fundamentals.txt @@ -0,0 +1,27 @@ +.. _laravel_fundamentals: + +============ +Fundamentals +============ + + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: php framework, odm + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + /read-operations + /write-operations + +Learn how to perform the following tasks by using the {+odm-long+} in the +following pages: + +- :ref:`Read Operations ` +- :ref:`Write Operations ` + diff --git a/docs/retrieve.txt b/docs/fundamentals/read-operations.txt similarity index 99% rename from docs/retrieve.txt rename to docs/fundamentals/read-operations.txt index b607d3d4f..c7a835c9d 100644 --- a/docs/retrieve.txt +++ b/docs/fundamentals/read-operations.txt @@ -1,4 +1,5 @@ .. _laravel-fundamentals-retrieve: +.. _laravel-fundamentals-read-ops: ============== Retrieve Data diff --git a/docs/index.txt b/docs/index.txt index febdb9371..c9c45d2dd 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -15,7 +15,7 @@ Laravel MongoDB /quick-start Release Notes - /retrieve + /fundamentals /eloquent-models /query-builder /user-authentication @@ -53,7 +53,8 @@ Fundamentals To learn how to perform the following tasks by using the {+odm-short+}, see the following content: -- :ref:`laravel-fundamentals-retrieve` +- :ref:`laravel-fundamentals-read-ops` +- :ref:`laravel-fundamentals-write-ops` - :ref:`laravel-eloquent-models` - :ref:`laravel-query-builder` - :ref:`laravel-user-authentication` From a5a75ca1474cd2e4e1725d0b5f379d13c7455259 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Thu, 28 Mar 2024 17:38:57 -0400 Subject: [PATCH 02/26] add examples --- docs/fundamentals/write-operations.txt | 118 ++++++++++++++++++ .../fundamentals/write-operations/Concert.php | 12 ++ .../write-operations/WriteOperationsTest.php | 99 +++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 docs/fundamentals/write-operations.txt create mode 100644 docs/includes/fundamentals/write-operations/Concert.php create mode 100644 docs/includes/fundamentals/write-operations/WriteOperationsTest.php diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt new file mode 100644 index 000000000..09cf3b982 --- /dev/null +++ b/docs/fundamentals/write-operations.txt @@ -0,0 +1,118 @@ +.. _laravel-fundamentals-write-ops: + +================ +Write Operations +================ + +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :keywords: insert, insert one, update, update one, upsert, delete, delete many, code example, mass assignment, eloquent model + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use {+odm-short+} to perform +**write operations** on your MongoDB collections. Write operations include +inserting, updating, and deleting data based on criteria that you specify. + +This guide shows you how to perform the following tasks: + +- Insert Documents +- Modify Documents +- Delete Documents + +.. _laravel-fundamentals-insert-documents: + +Insert Documents +---------------- + +In this section, you can learn how to insert documents into MongoDB collections +from your Laravel application by using the {+odm-long+}. + +When you insert the documents, make sure that the data does not violate any +unique indexes on the collection. When inserting the first document of a +collection or creating a new collection, MongoDB automatically creates a +unique index on the ``_id`` field. + +For more ionformation creating indexes on MongoDB collections by using the +Laravel schema builder, see the :ref:`laravel-eloquent-indexes` guide. + +This section uses the following example model class to demonstrate how to +use Eloquent models to perform insert operations: + +.. literalinclude:: /includes/fundamentals/write-operations/Concert.php + :language: php + :dedent: + :caption: Concert.php + +.. tip:: + + The ``$fillable`` attribute lets you use Laravel mass assignment for insert + operations. To learn more about mass assignment, see :ref:`laravel-model-mass-assignment`. + +To learn more about Eloquent models in {+odm-short+} see the :ref:`laravel-eloquent-models` +section. + +Insert a Document Examples +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The examples in this section show how to use the ``save()`` Eloquent method to +insert an instance of a ``Concert`` model as a MongoDB document. + +When the ``save()`` method succeeds, the instance on which you called the +method contains the model. If it fails, the instance is assigned a null value. + +The example code performs the following actions: + +- Creates a new instance of the ``Concert`` model +- Assigns string values to the ``performer`` and ``venue`` field +- Assigns a date to the ``performanceDate`` field by using the ``Carbon`` + package. +- Inserts the document by calling the ``save()`` method. + +.. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin model insert one + :end-before: end model insert one + +If you enable mass assignment by defining either the ``$fillable`` or +``$guarded`` attributes, you can use the Eloquent model ``create()`` method +to perform the insert in a single call as shown in the following example: + +.. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin model insert one mass assign + :end-before: end model insert one mass assign + +To learn more about the Carbon PHP API extension, see the +`Carbon `__ GitHub repository. + +Insert Multiple Documents Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The examples in this section show how to use the ``insert()`` Eloquent method +to insert multiple instances of a ``Concert`` model as MongoDB documents. + +When the ``insert()`` method succeeds, the method returns the value ``1``. +If it fails, the method throws an exception. + +The example code passes an array containing the data for multiple models +to the ``insert()`` method: + +.. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin model insert many + :end-before: end model insert many + diff --git a/docs/includes/fundamentals/write-operations/Concert.php b/docs/includes/fundamentals/write-operations/Concert.php new file mode 100644 index 000000000..e7c2dfc89 --- /dev/null +++ b/docs/includes/fundamentals/write-operations/Concert.php @@ -0,0 +1,12 @@ + 'datetime' ]; +} diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php new file mode 100644 index 000000000..d97dae535 --- /dev/null +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -0,0 +1,99 @@ + + + require_once __DIR__ . '/Concert.php'; + + Concert::truncate(); + + // begin model insert one + $concert = new Concert(); + $concert->performer = 'Mitsuko Uchida'; + $concert->venue = 'Carnegie Hall'; + $concert->performanceDate = Carbon::create(2024, 4, 1, 20, 0, 0, 'EST'); + $concert->save(); + // end model insert one + + $this->assertNotNull($concert); + + $result = Concert::first(); + $this->assertInstanceOf(Concert::class, $result); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testModelInsertMassAssign(): void + { + // + + require_once __DIR__ . '/Concert.php'; + + Concert::truncate(); + + // begin model insert one mass assign + $insertResult = Concert::create([ + 'performer' => 'The Rolling Stones', + 'venue' => 'Soldier Field', + 'performanceDate' => Carbon::create(2024, 6, 30, 20, 0, 0, 'CDT') + ]); + // end model insert one mass assign + + $this->assertNotNull($insertResult); + + $result = Concert::first(); + $this->assertInstanceOf(Concert::class, $result); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testModelInsertMany(): void + { + // + + require_once __DIR__ . '/Concert.php'; + + Concert::truncate(); + + // begin model insert many + $data = [ + [ + 'performer' => 'Brad Mehldau', + 'venue' => 'Philharmonie de Paris', + 'performanceDate' => Carbon::create(2025, 2, 12, 20, 0, 0, 'CET') + ], + [ + 'performer' => 'Billy Joel', + 'venue' => 'Madison Square Garden', + 'performanceDate' => Carbon::create(2024, 7, 25, 19, 0, 0, 'EST') + ] + ]; + Concert::insert($data); + // end model insert many + $results = Concert::get(); + + $this->assertEquals(2, count($results)); + } +} From a678179840d4a3dbce878ec36f710d81ef3d5fce Mon Sep 17 00:00:00 2001 From: ccho-mongodb Date: Thu, 28 Mar 2024 21:40:55 +0000 Subject: [PATCH 03/26] apply phpcbf formatting --- .../fundamentals/write-operations/Concert.php | 4 ++-- .../write-operations/WriteOperationsTest.php | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/includes/fundamentals/write-operations/Concert.php b/docs/includes/fundamentals/write-operations/Concert.php index e7c2dfc89..9eaa51139 100644 --- a/docs/includes/fundamentals/write-operations/Concert.php +++ b/docs/includes/fundamentals/write-operations/Concert.php @@ -7,6 +7,6 @@ class Concert extends Model { protected $connection = 'mongodb'; - protected $fillable = [ 'performer', 'venue', 'performanceDate' ]; - protected $casts = [ 'performanceDate' => 'datetime' ]; + protected $fillable = ['performer', 'venue', 'performanceDate']; + protected $casts = ['performanceDate' => 'datetime']; } diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index d97dae535..75c4cf116 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -4,12 +4,11 @@ namespace App\Http\Controllers; -use Illuminate\Database\Query\Builder; -use Illuminate\Support\Facades\DB; -use MongoDB\Laravel\Collection; -use MongoDB\Laravel\Tests\TestCase; use App\Models\Concert; use Carbon\Carbon; +use MongoDB\Laravel\Tests\TestCase; + +use function count; class WriteOperationsTest extends TestCase { @@ -55,7 +54,7 @@ public function testModelInsertMassAssign(): void $insertResult = Concert::create([ 'performer' => 'The Rolling Stones', 'venue' => 'Soldier Field', - 'performanceDate' => Carbon::create(2024, 6, 30, 20, 0, 0, 'CDT') + 'performanceDate' => Carbon::create(2024, 6, 30, 20, 0, 0, 'CDT'), ]); // end model insert one mass assign @@ -82,13 +81,13 @@ public function testModelInsertMany(): void [ 'performer' => 'Brad Mehldau', 'venue' => 'Philharmonie de Paris', - 'performanceDate' => Carbon::create(2025, 2, 12, 20, 0, 0, 'CET') + 'performanceDate' => Carbon::create(2025, 2, 12, 20, 0, 0, 'CET'), ], [ 'performer' => 'Billy Joel', 'venue' => 'Madison Square Garden', - 'performanceDate' => Carbon::create(2024, 7, 25, 19, 0, 0, 'EST') - ] + 'performanceDate' => Carbon::create(2024, 7, 25, 19, 0, 0, 'EST'), + ], ]; Concert::insert($data); // end model insert many From eea96e58b3aeabb8625baca0fc9446a3c9bd9455 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Thu, 28 Mar 2024 18:26:37 -0400 Subject: [PATCH 04/26] wip --- docs/fundamentals.txt | 5 ++--- docs/fundamentals/write-operations.txt | 19 ++++++++++++++++--- .../write-operations/WriteOperationsTest.php | 8 ++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/fundamentals.txt b/docs/fundamentals.txt index 6e2fa2c7f..738f8ec7a 100644 --- a/docs/fundamentals.txt +++ b/docs/fundamentals.txt @@ -4,7 +4,6 @@ Fundamentals ============ - .. facet:: :name: genre :values: reference @@ -16,8 +15,8 @@ Fundamentals :titlesonly: :maxdepth: 1 - /read-operations - /write-operations + /fundamentals/read-operations + /fundamentals/write-operations Learn how to perform the following tasks by using the {+odm-long+} in the following pages: diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 09cf3b982..43d16667d 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -59,6 +59,10 @@ use Eloquent models to perform insert operations: The ``$fillable`` attribute lets you use Laravel mass assignment for insert operations. To learn more about mass assignment, see :ref:`laravel-model-mass-assignment`. + The ``$casts`` attribute instructs Laravel to convert attributes to common + data types. To learn more, see `Attribute Casting `__ + in the Laravel documentation. + To learn more about Eloquent models in {+odm-short+} see the :ref:`laravel-eloquent-models` section. @@ -71,13 +75,13 @@ insert an instance of a ``Concert`` model as a MongoDB document. When the ``save()`` method succeeds, the instance on which you called the method contains the model. If it fails, the instance is assigned a null value. -The example code performs the following actions: +This example code performs the following actions: - Creates a new instance of the ``Concert`` model - Assigns string values to the ``performer`` and ``venue`` field - Assigns a date to the ``performanceDate`` field by using the ``Carbon`` - package. -- Inserts the document by calling the ``save()`` method. + package +- Inserts the document by calling the ``save()`` method .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php :language: php @@ -85,6 +89,15 @@ The example code performs the following actions: :start-after: begin model insert one :end-before: end model insert one +You can retrieve the inserted document id value by accessing the ``id`` member +of the model as shown in the following code example: + +.. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin inserted id + :end-before: end inserted id + If you enable mass assignment by defining either the ``$fillable`` or ``$guarded`` attributes, you can use the Eloquent model ``create()`` method to perform the insert in a single call as shown in the following example: diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index 75c4cf116..b2902cd56 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -32,6 +32,12 @@ public function testModelInsert(): void $concert->save(); // end model insert one + // begin inserted id + $insertedId = $concert->id; + // end inserted id + + + print_r($insertedId); $this->assertNotNull($concert); $result = Concert::first(); @@ -89,8 +95,10 @@ public function testModelInsertMany(): void 'performanceDate' => Carbon::create(2024, 7, 25, 19, 0, 0, 'EST'), ], ]; + Concert::insert($data); // end model insert many + $results = Concert::get(); $this->assertEquals(2, count($results)); From 88024a53f97b2db47a0720af78643ae927a8ed15 Mon Sep 17 00:00:00 2001 From: ccho-mongodb Date: Thu, 28 Mar 2024 23:04:52 +0000 Subject: [PATCH 05/26] apply phpcbf formatting --- .../fundamentals/write-operations/WriteOperationsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index b2902cd56..f00bf3792 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -9,6 +9,7 @@ use MongoDB\Laravel\Tests\TestCase; use function count; +use function print_r; class WriteOperationsTest extends TestCase { @@ -36,7 +37,6 @@ public function testModelInsert(): void $insertedId = $concert->id; // end inserted id - print_r($insertedId); $this->assertNotNull($concert); From 24fdd13fc71aed3f6722673f73d0195b8553227a Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Fri, 29 Mar 2024 11:25:16 -0400 Subject: [PATCH 06/26] add date info --- docs/fundamentals/write-operations.txt | 18 +++++++++++++----- .../write-operations/WriteOperationsTest.php | 7 ++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 43d16667d..acf00f8ac 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -26,7 +26,7 @@ inserting, updating, and deleting data based on criteria that you specify. This guide shows you how to perform the following tasks: -- Insert Documents +- :ref:`laravel-fundamentals-insert-documents` - Modify Documents - Delete Documents @@ -43,7 +43,7 @@ unique indexes on the collection. When inserting the first document of a collection or creating a new collection, MongoDB automatically creates a unique index on the ``_id`` field. -For more ionformation creating indexes on MongoDB collections by using the +For more information creating indexes on MongoDB collections by using the Laravel schema builder, see the :ref:`laravel-eloquent-indexes` guide. This section uses the following example model class to demonstrate how to @@ -114,14 +114,22 @@ To learn more about the Carbon PHP API extension, see the Insert Multiple Documents Example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The examples in this section show how to use the ``insert()`` Eloquent method +The example in this section show how to use the ``insert()`` Eloquent method to insert multiple instances of a ``Concert`` model as MongoDB documents. +This bulk insert method reduces the number of calls that your application needs +to make to save the documents. When the ``insert()`` method succeeds, the method returns the value ``1``. If it fails, the method throws an exception. -The example code passes an array containing the data for multiple models -to the ``insert()`` method: +The example code saves multiple models in a single call by passing them as +an array to ``insert()`` method: + +.. note:: + + This example wraps the dates in the `MongoDB\BSON\UTCDateTime <{+phplib-api+}/class.mongodb-bson-utcdatetime.php>`__ + class to convert it to a type that MongoDB can serialize because Laravel + skips attribute casting on bulk insert operations. .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php :language: php diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index f00bf3792..645522ce6 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -6,6 +6,7 @@ use App\Models\Concert; use Carbon\Carbon; +use MongoDB\BSON\UTCDateTime; use MongoDB\Laravel\Tests\TestCase; use function count; @@ -37,8 +38,8 @@ public function testModelInsert(): void $insertedId = $concert->id; // end inserted id - print_r($insertedId); $this->assertNotNull($concert); + $this->assertNotNull($insertedId); $result = Concert::first(); $this->assertInstanceOf(Concert::class, $result); @@ -87,12 +88,12 @@ public function testModelInsertMany(): void [ 'performer' => 'Brad Mehldau', 'venue' => 'Philharmonie de Paris', - 'performanceDate' => Carbon::create(2025, 2, 12, 20, 0, 0, 'CET'), + 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), ], [ 'performer' => 'Billy Joel', 'venue' => 'Madison Square Garden', - 'performanceDate' => Carbon::create(2024, 7, 25, 19, 0, 0, 'EST'), + 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), ], ]; From 77bdbec9ab18874150a43dbfed26824dc45a7830 Mon Sep 17 00:00:00 2001 From: ccho-mongodb Date: Fri, 29 Mar 2024 15:28:29 +0000 Subject: [PATCH 07/26] apply phpcbf formatting --- .../fundamentals/write-operations/WriteOperationsTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index 645522ce6..f9f5d62fe 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -10,7 +10,6 @@ use MongoDB\Laravel\Tests\TestCase; use function count; -use function print_r; class WriteOperationsTest extends TestCase { From 831f06e0b26fed55d690696164bf7d8a602327e9 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Fri, 29 Mar 2024 11:33:31 -0400 Subject: [PATCH 08/26] update title of read operations --- docs/fundamentals/read-operations.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/fundamentals/read-operations.txt b/docs/fundamentals/read-operations.txt index c7a835c9d..ff6c7814f 100644 --- a/docs/fundamentals/read-operations.txt +++ b/docs/fundamentals/read-operations.txt @@ -1,9 +1,9 @@ .. _laravel-fundamentals-retrieve: .. _laravel-fundamentals-read-ops: -============== -Retrieve Data -============== +=============== +Read Operations +=============== .. facet:: :name: genre From d813f23779739daa018c8e5adece573bc41ab2dd Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Fri, 29 Mar 2024 11:41:55 -0400 Subject: [PATCH 09/26] grammar fixes --- docs/fundamentals/write-operations.txt | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index acf00f8ac..b049b5a34 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -22,7 +22,7 @@ Overview In this guide, you can learn how to use {+odm-short+} to perform **write operations** on your MongoDB collections. Write operations include -inserting, updating, and deleting data based on criteria that you specify. +inserting, updating, and deleting data based on specified criteria. This guide shows you how to perform the following tasks: @@ -38,12 +38,12 @@ Insert Documents In this section, you can learn how to insert documents into MongoDB collections from your Laravel application by using the {+odm-long+}. -When you insert the documents, make sure that the data does not violate any +When you insert the documents, ensure the data does not violate any unique indexes on the collection. When inserting the first document of a collection or creating a new collection, MongoDB automatically creates a unique index on the ``_id`` field. -For more information creating indexes on MongoDB collections by using the +For more information on creating indexes on MongoDB collections by using the Laravel schema builder, see the :ref:`laravel-eloquent-indexes` guide. This section uses the following example model class to demonstrate how to @@ -69,8 +69,8 @@ section. Insert a Document Examples ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The examples in this section show how to use the ``save()`` Eloquent method to -insert an instance of a ``Concert`` model as a MongoDB document. +These examples show how to use the ``save()`` Eloquent method to insert an +instance of a ``Concert`` model as a MongoDB document. When the ``save()`` method succeeds, the instance on which you called the method contains the model. If it fails, the instance is assigned a null value. @@ -89,8 +89,8 @@ This example code performs the following actions: :start-after: begin model insert one :end-before: end model insert one -You can retrieve the inserted document id value by accessing the ``id`` member -of the model as shown in the following code example: +You can retrieve the inserted document's ``_id`` value by accessing the model's +``id`` member as shown in the following code example: .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php :language: php @@ -114,13 +114,13 @@ To learn more about the Carbon PHP API extension, see the Insert Multiple Documents Example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The example in this section show how to use the ``insert()`` Eloquent method -to insert multiple instances of a ``Concert`` model as MongoDB documents. -This bulk insert method reduces the number of calls that your application needs -to make to save the documents. +This example shows how to use the ``insert()`` Eloquent method to insert +multiple instances of a ``Concert`` model as MongoDB documents. This bulk +insert method reduces the number of calls your application needs to make +to save the documents. -When the ``insert()`` method succeeds, the method returns the value ``1``. -If it fails, the method throws an exception. +When the ``insert()`` method succeeds, it returns the value ``1``. If it +fails, it throws an exception. The example code saves multiple models in a single call by passing them as an array to ``insert()`` method: @@ -128,7 +128,7 @@ an array to ``insert()`` method: .. note:: This example wraps the dates in the `MongoDB\BSON\UTCDateTime <{+phplib-api+}/class.mongodb-bson-utcdatetime.php>`__ - class to convert it to a type that MongoDB can serialize because Laravel + class to convert it to a type MongoDB can serialize because Laravel skips attribute casting on bulk insert operations. .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php From a194e6098730dc2e272b99130907e91f9f8ce6fc Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 14:53:07 -0400 Subject: [PATCH 10/26] DOCSP-35947: write operations - modify documents --- docs/fundamentals.txt | 3 +- docs/fundamentals/write-operations.txt | 153 +++++++++++++++--- .../fundamentals/write-operations/Concert.php | 2 +- .../write-operations/WriteOperationsTest.php | 123 ++++++++++++++ 4 files changed, 253 insertions(+), 28 deletions(-) diff --git a/docs/fundamentals.txt b/docs/fundamentals.txt index 738f8ec7a..041388350 100644 --- a/docs/fundamentals.txt +++ b/docs/fundamentals.txt @@ -18,8 +18,7 @@ Fundamentals /fundamentals/read-operations /fundamentals/write-operations -Learn how to perform the following tasks by using the {+odm-long+} in the -following pages: +Learn how to use the {+odm-long+} to perform the following tasks: - :ref:`Read Operations ` - :ref:`Write Operations ` diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index b049b5a34..2ff7bdf76 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -9,7 +9,7 @@ Write Operations :values: tutorial .. meta:: - :keywords: insert, insert one, update, update one, upsert, delete, delete many, code example, mass assignment, eloquent model + :keywords: insert, insert one, code example, mass assignment, eloquent model .. contents:: On this page :local: @@ -27,27 +27,15 @@ inserting, updating, and deleting data based on specified criteria. This guide shows you how to perform the following tasks: - :ref:`laravel-fundamentals-insert-documents` -- Modify Documents +- :ref:`laravel-modify-documents` - Delete Documents -.. _laravel-fundamentals-insert-documents: +.. _laravel-fundamentals-write-sample-model: -Insert Documents ----------------- +Sample Model +~~~~~~~~~~~~ -In this section, you can learn how to insert documents into MongoDB collections -from your Laravel application by using the {+odm-long+}. - -When you insert the documents, ensure the data does not violate any -unique indexes on the collection. When inserting the first document of a -collection or creating a new collection, MongoDB automatically creates a -unique index on the ``_id`` field. - -For more information on creating indexes on MongoDB collections by using the -Laravel schema builder, see the :ref:`laravel-eloquent-indexes` guide. - -This section uses the following example model class to demonstrate how to -use Eloquent models to perform insert operations: +The write operations in this guide refer to the following Eloquent model class: .. literalinclude:: /includes/fundamentals/write-operations/Concert.php :language: php @@ -57,13 +45,31 @@ use Eloquent models to perform insert operations: .. tip:: The ``$fillable`` attribute lets you use Laravel mass assignment for insert - operations. To learn more about mass assignment, see :ref:`laravel-model-mass-assignment`. + operations. To learn more about mass assignment, see :ref:`laravel-model-mass-assignment` + in the Eloquent Model Class documentation. The ``$casts`` attribute instructs Laravel to convert attributes to common data types. To learn more, see `Attribute Casting `__ in the Laravel documentation. -To learn more about Eloquent models in {+odm-short+} see the :ref:`laravel-eloquent-models` +.. _laravel-fundamentals-insert-documents: + +Insert Documents +---------------- + +In this section, you can learn how to insert documents into MongoDB collections +from your Laravel application by using the {+odm-long+}. + +When you insert the documents, ensure the data does not violate any +unique indexes on the collection. When inserting the first document of a +collection or creating a new collection, MongoDB automatically creates a +unique index on the ``_id`` field. + +For more information on creating indexes on MongoDB collections by using the +Laravel schema builder, see the :ref:`laravel-eloquent-indexes` section +of the Schema Builder documentation. + +To learn more about Eloquent models in {+odm-short+}, see the :ref:`laravel-eloquent-models` section. Insert a Document Examples @@ -72,13 +78,15 @@ Insert a Document Examples These examples show how to use the ``save()`` Eloquent method to insert an instance of a ``Concert`` model as a MongoDB document. -When the ``save()`` method succeeds, the instance on which you called the -method contains the model. If it fails, the instance is assigned a null value. +When the ``save()`` method succeeds, the model instance on which you called the +method. If the operation fails, the model instance is assigned a null value. This example code performs the following actions: - Creates a new instance of the ``Concert`` model -- Assigns string values to the ``performer`` and ``venue`` field +- Assigns string values to the ``performer`` and ``venue`` fields +- Assigns an array of strings to the ``genre`` field +- Assigns a number to the ``ticketsSold`` field - Assigns a date to the ``performanceDate`` field by using the ``Carbon`` package - Inserts the document by calling the ``save()`` method @@ -109,7 +117,7 @@ to perform the insert in a single call as shown in the following example: :end-before: end model insert one mass assign To learn more about the Carbon PHP API extension, see the -`Carbon `__ GitHub repository. +:github:`Carbon ` GitHub repository. Insert Multiple Documents Example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -123,7 +131,7 @@ When the ``insert()`` method succeeds, it returns the value ``1``. If it fails, it throws an exception. The example code saves multiple models in a single call by passing them as -an array to ``insert()`` method: +an array to the ``insert()`` method: .. note:: @@ -137,3 +145,98 @@ an array to ``insert()`` method: :start-after: begin model insert many :end-before: end model insert many +.. _laravel-fundamentals-modify-documents: + +Modify Documents +---------------- + +In this section, you can learn how to modify documents in your MongoDB +collection from your Laravel application. Use update operations to modify +existing documents or to insert a document if no search criteria match. + +The Eloquent ORM lets you specify criteria to retrieve documents, perform +field on the returned object collections, and save them. + +This section provides examples of the following update operations: + +- :ref:`Update a document <>` +- :ref:`Update multiple documents <>` +- :ref:`Update an array in a document <>` +- :ref:`Upsert a document <>` + +Update a Document Examples +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can update a document in the following ways: + +- Modify an instance of the model and save the changes by calling the ``save()`` + method +- Use the fluent syntax to retrieve a matching document and apply updates to + it by calling the ``update()`` method or other helper methods + +The following example shows how to update a document by modifying an instance +of the model and calling its ``save()`` method: + +.. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin model update one save + :end-before: end model update one save + +When the ``save()`` method succeeds, the model instance on which you called the +method. If the operation fails, {+odm-short+} assigns the model instance a +null value. + +The following example shows how to update a document by using fluent syntax to +retrieve the first match and apply updates to the matching document: + +.. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin model update one save + :end-before: end model update one save + +.. note:: + + The ``orderBy()`` call sorts the results by the ``_id`` field in order to + guarantee a consistent result when the query matches multiple result. To + learn more about sorting in MongoDB, see :manual:`Natural order ` + glossary entry in the {+server-docs-name+}. + +When the ``update()`` method succeeds, the operation returns the number of +documents updated. If the retrieve part of the call does not match any +documents in the collection, {+odm-short+} returns the following error: + +.. code-block:: + :language: none + :copyable; false + + Error: Call to a member function update() on null + +Update Multiple Documents Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To perform a single update on one or more documents, call the ``update()`` +method on a collection of model objects. You can use the fluent syntax to +retrieve a collection of model objects that match your criteria and then +pass the updates in a call the ``update()`` method. + +The following example shows how to chain calls to retrieve a collection of +model objects and apply updates to all matching documents: + +.. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin model update one save + :end-before: end model update one save + +When the ``update()`` method succeeds, the operation returns the number of +documents updated. If the retrieve part of the call does not match any +documents in the collection, {+odm-short+} returns the following error: + +.. code-block:: + :language: none + :copyable; false + + Error: Call to a member function update() on null + diff --git a/docs/includes/fundamentals/write-operations/Concert.php b/docs/includes/fundamentals/write-operations/Concert.php index 9eaa51139..6472e82cf 100644 --- a/docs/includes/fundamentals/write-operations/Concert.php +++ b/docs/includes/fundamentals/write-operations/Concert.php @@ -7,6 +7,6 @@ class Concert extends Model { protected $connection = 'mongodb'; - protected $fillable = ['performer', 'venue', 'performanceDate']; + protected $fillable = ['performer', 'venue', 'genres', 'ticketsSold', 'performanceDate' ]; protected $casts = ['performanceDate' => 'datetime']; } diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index f9f5d62fe..316b5a256 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -29,6 +29,8 @@ public function testModelInsert(): void $concert = new Concert(); $concert->performer = 'Mitsuko Uchida'; $concert->venue = 'Carnegie Hall'; + $concert->genres = [ 'classical' ]; + $concert->ticketsSold = 2121; $concert->performanceDate = Carbon::create(2024, 4, 1, 20, 0, 0, 'EST'); $concert->save(); // end model insert one @@ -60,6 +62,8 @@ public function testModelInsertMassAssign(): void $insertResult = Concert::create([ 'performer' => 'The Rolling Stones', 'venue' => 'Soldier Field', + 'genres' => [ 'rock', 'pop', 'blues' ], + 'ticketsSold' => 59527, 'performanceDate' => Carbon::create(2024, 6, 30, 20, 0, 0, 'CDT'), ]); // end model insert one mass assign @@ -87,11 +91,15 @@ public function testModelInsertMany(): void [ 'performer' => 'Brad Mehldau', 'venue' => 'Philharmonie de Paris', + 'genres' => [ 'jazz', 'post-bop' ], + 'ticketsSold' => 5745, 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), ], [ 'performer' => 'Billy Joel', 'venue' => 'Madison Square Garden', + 'genres' => [ 'rock', 'soft rock', 'pop rock' ], + 'ticketsSold' => 12852, 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), ], ]; @@ -103,4 +111,119 @@ public function testModelInsertMany(): void $this->assertEquals(2, count($results)); } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testModelUpdateSave(): void + { + // + + require_once __DIR__ . '/Concert.php'; + Concert::truncate(); + + // insert the model + Concert::create([ + 'performer' => 'Brad Mehldau', + 'venue' => 'Philharmonie de Paris', + 'genres' => [ 'jazz', 'post-bop' ], + 'ticketsSold' => 5745, + 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), + ]); + + // begin model update one save + $concert = Concert::first(); + $concert->venue = 'Manchester Arena'; + $concert->ticketsSold = 9543; + $concert->save(); + // end model update one save + + $result = Concert::first(); + $this->assertInstanceOf(Concert::class, $result); + + $this->assertNotNull($result); + $this->assertEquals('Manchester Arena', $result->venue); + $this->assertEquals('Brad Mehldau', $result->performer); + $this->assertEquals(9543, $result->ticketsSold); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testModelUpdateFluent(): void + { + // + + require_once __DIR__ . '/Concert.php'; + Concert::truncate(); + + // insert the model + Concert::create([ + 'performer' => 'Brad Mehldau', + 'venue' => 'Philharmonie de Paris', + 'genres' => [ 'jazz', 'post-bop' ], + 'ticketsSold' => 5745, + 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), + ]); + + // begin model update one fluent + $concert = Concert::where(['performer' => 'Brad Mehldau']) + ->orderBy('_id') + ->first() + ->update([ 'venue' => 'Manchester Arena', 'ticketsSold' => 9543 ]); + // end model update one fluent + + $result = Concert::first(); + $this->assertInstanceOf(Concert::class, $result); + + $this->assertNotNull($result); + $this->assertEquals('Manchester Arena', $result->venue); + $this->assertEquals('Brad Mehldau', $result->performer); + $this->assertEquals(9543, $result->ticketsSold); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testModelUpdateMultiple(): void + { + // + + require_once __DIR__ . '/Concert.php'; + Concert::truncate(); + + // insert the model + Concert::create([ + 'performer' => 'Brad Mehldau', + 'venue' => 'Philharmonie de Paris', + 'genres' => [ 'jazz', 'post-bop' ], + 'ticketsSold' => 5745, + 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), + ]); + + Concert::create([ + 'performer' => 'The Rolling Stones', + 'venue' => 'Soldier Field', + 'genres' => [ 'rock', 'pop', 'blues' ], + 'ticketsSold' => 59527, + 'performanceDate' => Carbon::create(2024, 6, 30, 20, 0, 0, 'CDT'), + ]); + // begin model update multiple + Concert::whereIn('venue', ['Philharmonie de Paris', 'Soldier Field']) + ->update([ 'venue' => 'Concertgebouw', 'ticketsSold' => 0 ]); + // end model update multiple + + $results = Concert::get(); + + foreach ($results as $result) { + $this->assertInstanceOf(Concert::class, $result); + + $this->assertNotNull($result); + $this->assertEquals('Concertgebouw', $result->venue); + $this->assertEquals(0, $result->ticketsSold); + } + } } From 2582bd5f9836210ae3fb69a63f4863212882de15 Mon Sep 17 00:00:00 2001 From: ccho-mongodb Date: Mon, 1 Apr 2024 18:55:16 +0000 Subject: [PATCH 11/26] apply phpcbf formatting --- docs/includes/fundamentals/write-operations/Concert.php | 2 +- .../fundamentals/write-operations/WriteOperationsTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/includes/fundamentals/write-operations/Concert.php b/docs/includes/fundamentals/write-operations/Concert.php index 6472e82cf..69b36b9a5 100644 --- a/docs/includes/fundamentals/write-operations/Concert.php +++ b/docs/includes/fundamentals/write-operations/Concert.php @@ -7,6 +7,6 @@ class Concert extends Model { protected $connection = 'mongodb'; - protected $fillable = ['performer', 'venue', 'genres', 'ticketsSold', 'performanceDate' ]; + protected $fillable = ['performer', 'venue', 'genres', 'ticketsSold', 'performanceDate']; protected $casts = ['performanceDate' => 'datetime']; } diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index 316b5a256..f45f6f3de 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -29,7 +29,7 @@ public function testModelInsert(): void $concert = new Concert(); $concert->performer = 'Mitsuko Uchida'; $concert->venue = 'Carnegie Hall'; - $concert->genres = [ 'classical' ]; + $concert->genres = ['classical']; $concert->ticketsSold = 2121; $concert->performanceDate = Carbon::create(2024, 4, 1, 20, 0, 0, 'EST'); $concert->save(); @@ -172,7 +172,7 @@ public function testModelUpdateFluent(): void $concert = Concert::where(['performer' => 'Brad Mehldau']) ->orderBy('_id') ->first() - ->update([ 'venue' => 'Manchester Arena', 'ticketsSold' => 9543 ]); + ->update(['venue' => 'Manchester Arena', 'ticketsSold' => 9543]); // end model update one fluent $result = Concert::first(); @@ -213,7 +213,7 @@ public function testModelUpdateMultiple(): void ]); // begin model update multiple Concert::whereIn('venue', ['Philharmonie de Paris', 'Soldier Field']) - ->update([ 'venue' => 'Concertgebouw', 'ticketsSold' => 0 ]); + ->update(['venue' => 'Concertgebouw', 'ticketsSold' => 0]); // end model update multiple $results = Concert::get(); From 86ff66367a36f402f72c14b457dee5ceb00c69e1 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 16:21:15 -0400 Subject: [PATCH 12/26] misc fixes --- docs/fundamentals/write-operations.txt | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 2ff7bdf76..c30e4ecd1 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -98,7 +98,7 @@ This example code performs the following actions: :end-before: end model insert one You can retrieve the inserted document's ``_id`` value by accessing the model's -``id`` member as shown in the following code example: +``id`` member, as shown in the following code example: .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php :language: php @@ -108,7 +108,7 @@ You can retrieve the inserted document's ``_id`` value by accessing the model's If you enable mass assignment by defining either the ``$fillable`` or ``$guarded`` attributes, you can use the Eloquent model ``create()`` method -to perform the insert in a single call as shown in the following example: +to perform the insert in a single call, as shown in the following example: .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php :language: php @@ -154,15 +154,15 @@ In this section, you can learn how to modify documents in your MongoDB collection from your Laravel application. Use update operations to modify existing documents or to insert a document if no search criteria match. -The Eloquent ORM lets you specify criteria to retrieve documents, perform -field on the returned object collections, and save them. +Eloquent lets you specify criteria to retrieve documents, perform updates on +the returned object collections, and save them. This section provides examples of the following update operations: -- :ref:`Update a document <>` -- :ref:`Update multiple documents <>` -- :ref:`Update an array in a document <>` -- :ref:`Upsert a document <>` +- :ref:`Update a document ` +- :ref:`Update multiple documents ` + +.. _laravel-modify-documents-update-one: Update a Document Examples ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -198,9 +198,9 @@ retrieve the first match and apply updates to the matching document: .. note:: - The ``orderBy()`` call sorts the results by the ``_id`` field in order to - guarantee a consistent result when the query matches multiple result. To - learn more about sorting in MongoDB, see :manual:`Natural order ` + The ``orderBy()`` call sorts the results by the ``_id`` field to + guarantee a consistent sort order when the query matches multiple results. + To learn more about sorting in MongoDB, see :manual:`Natural order ` glossary entry in the {+server-docs-name+}. When the ``update()`` method succeeds, the operation returns the number of @@ -213,13 +213,15 @@ documents in the collection, {+odm-short+} returns the following error: Error: Call to a member function update() on null +.. _laravel-modify-documents-update-multiple: + Update Multiple Documents Example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To perform a single update on one or more documents, call the ``update()`` method on a collection of model objects. You can use the fluent syntax to retrieve a collection of model objects that match your criteria and then -pass the updates in a call the ``update()`` method. +pass your updates to the ``update()`` method. The following example shows how to chain calls to retrieve a collection of model objects and apply updates to all matching documents: From 4dc106a1dc18a117067a7e76f4644db38495fcb2 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 16:30:17 -0400 Subject: [PATCH 13/26] rst fixes --- docs/fundamentals/write-operations.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index c30e4ecd1..a9d9da781 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -27,7 +27,7 @@ inserting, updating, and deleting data based on specified criteria. This guide shows you how to perform the following tasks: - :ref:`laravel-fundamentals-insert-documents` -- :ref:`laravel-modify-documents` +- :ref:`laravel-fundamentals-modify-documents` - Delete Documents .. _laravel-fundamentals-write-sample-model: @@ -209,7 +209,7 @@ documents in the collection, {+odm-short+} returns the following error: .. code-block:: :language: none - :copyable; false + :copyable: false Error: Call to a member function update() on null @@ -238,7 +238,7 @@ documents in the collection, {+odm-short+} returns the following error: .. code-block:: :language: none - :copyable; false + :copyable: false Error: Call to a member function update() on null From 678490ef28e8514128b1b04254107bf62c6c966a Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 16:39:01 -0400 Subject: [PATCH 14/26] fixes --- docs/fundamentals/write-operations.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index a9d9da781..44c8dbc78 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -35,7 +35,7 @@ This guide shows you how to perform the following tasks: Sample Model ~~~~~~~~~~~~ -The write operations in this guide refer to the following Eloquent model class: +The write operations in this guide reference the following Eloquent model class: .. literalinclude:: /includes/fundamentals/write-operations/Concert.php :language: php @@ -152,7 +152,8 @@ Modify Documents In this section, you can learn how to modify documents in your MongoDB collection from your Laravel application. Use update operations to modify -existing documents or to insert a document if no search criteria match. +existing documents or to insert a document if no documents match the search +criteria. Eloquent lets you specify criteria to retrieve documents, perform updates on the returned object collections, and save them. @@ -170,9 +171,9 @@ Update a Document Examples You can update a document in the following ways: - Modify an instance of the model and save the changes by calling the ``save()`` - method + method. - Use the fluent syntax to retrieve a matching document and apply updates to - it by calling the ``update()`` method or other helper methods + it by calling the ``update()`` method or other helper methods. The following example shows how to update a document by modifying an instance of the model and calling its ``save()`` method: @@ -200,7 +201,7 @@ retrieve the first match and apply updates to the matching document: The ``orderBy()`` call sorts the results by the ``_id`` field to guarantee a consistent sort order when the query matches multiple results. - To learn more about sorting in MongoDB, see :manual:`Natural order ` + To learn more about sorting in MongoDB, see the :manual:`Natural order ` glossary entry in the {+server-docs-name+}. When the ``update()`` method succeeds, the operation returns the number of @@ -229,8 +230,8 @@ model objects and apply updates to all matching documents: .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php :language: php :dedent: - :start-after: begin model update one save - :end-before: end model update one save + :start-after: begin model update multiple + :end-before: end model update multiple When the ``update()`` method succeeds, the operation returns the number of documents updated. If the retrieve part of the call does not match any From 8ff687269df4ff6a64cb24021a3e9aacf936d366 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 16:43:13 -0400 Subject: [PATCH 15/26] fix --- docs/fundamentals/write-operations.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 44c8dbc78..7a8208414 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -219,7 +219,7 @@ documents in the collection, {+odm-short+} returns the following error: Update Multiple Documents Example ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To perform a single update on one or more documents, call the ``update()`` +To perform an update on one or more documents, call the ``update()`` method on a collection of model objects. You can use the fluent syntax to retrieve a collection of model objects that match your criteria and then pass your updates to the ``update()`` method. From 44eb655da540a2a3a0fad3303cea2293c48c6073 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 17:33:18 -0400 Subject: [PATCH 16/26] fix --- docs/fundamentals/write-operations.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 7a8208414..d1ac3e4ef 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -194,8 +194,8 @@ retrieve the first match and apply updates to the matching document: .. literalinclude:: /includes/fundamentals/write-operations/WriteOperationsTest.php :language: php :dedent: - :start-after: begin model update one save - :end-before: end model update one save + :start-after: begin model update one fluent + :end-before: end model update one fluent .. note:: From 60a6cfb3f3ba0e76a7634bddfad8582524066ec5 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 17:34:46 -0400 Subject: [PATCH 17/26] fix rst --- docs/fundamentals/write-operations.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index d1ac3e4ef..2b53d15ac 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -208,8 +208,7 @@ When the ``update()`` method succeeds, the operation returns the number of documents updated. If the retrieve part of the call does not match any documents in the collection, {+odm-short+} returns the following error: -.. code-block:: - :language: none +.. code-block:: none :copyable: false Error: Call to a member function update() on null @@ -237,8 +236,7 @@ When the ``update()`` method succeeds, the operation returns the number of documents updated. If the retrieve part of the call does not match any documents in the collection, {+odm-short+} returns the following error: -.. code-block:: - :language: none +.. code-block:: none :copyable: false Error: Call to a member function update() on null From a9d072c4521c971fe32fe933a7727d809d59e169 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 17:42:01 -0400 Subject: [PATCH 18/26] concise sentence --- docs/fundamentals/write-operations.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 2b53d15ac..96367cf33 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -200,8 +200,8 @@ retrieve the first match and apply updates to the matching document: .. note:: The ``orderBy()`` call sorts the results by the ``_id`` field to - guarantee a consistent sort order when the query matches multiple results. - To learn more about sorting in MongoDB, see the :manual:`Natural order ` + guarantee a consistent sort order. To learn more about sorting in MongoDB, + see the :manual:`Natural order ` glossary entry in the {+server-docs-name+}. When the ``update()`` method succeeds, the operation returns the number of From 79037d20b1a07bd8e566bf8f09d85493476031bb Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 17:43:50 -0400 Subject: [PATCH 19/26] linebreaks --- docs/fundamentals/write-operations.txt | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 96367cf33..c68bcc6fa 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -79,7 +79,9 @@ These examples show how to use the ``save()`` Eloquent method to insert an instance of a ``Concert`` model as a MongoDB document. When the ``save()`` method succeeds, the model instance on which you called the -method. If the operation fails, the model instance is assigned a null value. +method. + +If the operation fails, the model instance is assigned a null value. This example code performs the following actions: @@ -127,8 +129,9 @@ multiple instances of a ``Concert`` model as MongoDB documents. This bulk insert method reduces the number of calls your application needs to make to save the documents. -When the ``insert()`` method succeeds, it returns the value ``1``. If it -fails, it throws an exception. +When the ``insert()`` method succeeds, it returns the value ``1``. + +If it fails, it throws an exception. The example code saves multiple models in a single call by passing them as an array to the ``insert()`` method: @@ -185,8 +188,9 @@ of the model and calling its ``save()`` method: :end-before: end model update one save When the ``save()`` method succeeds, the model instance on which you called the -method. If the operation fails, {+odm-short+} assigns the model instance a -null value. +method. + +If the operation fails, {+odm-short+} assigns the model instance a null value. The following example shows how to update a document by using fluent syntax to retrieve the first match and apply updates to the matching document: @@ -205,8 +209,10 @@ retrieve the first match and apply updates to the matching document: glossary entry in the {+server-docs-name+}. When the ``update()`` method succeeds, the operation returns the number of -documents updated. If the retrieve part of the call does not match any -documents in the collection, {+odm-short+} returns the following error: +documents updated. + +If the retrieve part of the call does not match any documents in the collection, +{+odm-short+} returns the following error: .. code-block:: none :copyable: false @@ -233,8 +239,10 @@ model objects and apply updates to all matching documents: :end-before: end model update multiple When the ``update()`` method succeeds, the operation returns the number of -documents updated. If the retrieve part of the call does not match any -documents in the collection, {+odm-short+} returns the following error: +documents updated. + +If the retrieve part of the call does not match any documents in the +collection, {+odm-short+} returns the following error: .. code-block:: none :copyable: false From 78bc0e77d9c98822e5cafb3ef581f93691821ee2 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 17:46:59 -0400 Subject: [PATCH 20/26] double backslash --- docs/fundamentals/write-operations.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index c68bcc6fa..c04f76299 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -138,7 +138,7 @@ an array to the ``insert()`` method: .. note:: - This example wraps the dates in the `MongoDB\BSON\UTCDateTime <{+phplib-api+}/class.mongodb-bson-utcdatetime.php>`__ + This example wraps the dates in the `MongoDB\\BSON\\UTCDateTime <{+phplib-api+}/class.mongodb-bson-utcdatetime.php>`__ class to convert it to a type MongoDB can serialize because Laravel skips attribute casting on bulk insert operations. From 1d7715303f5048e5e4b30b52b47bd7ae96c7f1b6 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Mon, 1 Apr 2024 17:48:42 -0400 Subject: [PATCH 21/26] fix --- docs/fundamentals/write-operations.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index c04f76299..624c19e30 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -78,8 +78,8 @@ Insert a Document Examples These examples show how to use the ``save()`` Eloquent method to insert an instance of a ``Concert`` model as a MongoDB document. -When the ``save()`` method succeeds, the model instance on which you called the -method. +When the ``save()`` method succeeds, you can access the model instance on +which you called the method. If the operation fails, the model instance is assigned a null value. From 39eb362362d98bb0f9c9ba89a09cade7393446e2 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Tue, 2 Apr 2024 13:52:01 -0400 Subject: [PATCH 22/26] DOCSP-35949: Write Operations - Upsert --- docs/fundamentals/write-operations.txt | 69 ++++++++++++++++++- .../write-operations/WriteOperationsTest.php | 26 +++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 624c19e30..625fcccd8 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -9,7 +9,7 @@ Write Operations :values: tutorial .. meta:: - :keywords: insert, insert one, code example, mass assignment, eloquent model + :keywords: insert, insert one, update, update one, upsert, code example, mass assignment, eloquent model .. contents:: On this page :local: @@ -165,6 +165,7 @@ This section provides examples of the following update operations: - :ref:`Update a document ` - :ref:`Update multiple documents ` +- :ref:`Update or insert in a single operation ` .. _laravel-modify-documents-update-one: @@ -249,3 +250,69 @@ collection, {+odm-short+} returns the following error: Error: Call to a member function update() on null +.. _laravel-modify-documents-upsert: + +Update or Insert in a Single Operation +-------------------------------------- + +An **upsert** operation lets you perform an update or insert in a single +operation. This operation streamlines the task of updating a document or +inserting one if it does not exist. + +To specify an upsert in an ``update()`` method, set the ``upsert`` option to +``true`` as shown in the following code example: + +.. code-block:: php + :emphasize-lines: 4 + :copyable: false + + YourModel::where() + ->update( + [], + [upsert => true] + ); + +This operation performs one of the following actions: + +- If the ``update()`` method is chained to a query that matches documents, + it updates the matching documents. +- If the ``update()`` method is chained to a query that matches zero documents, + it inserts a document that contains the update data and the equality match + criteria data. + +Upsert Example +~~~~~~~~~~~~~~ + +This example shows how to pass the ``upsert`` option to the ``update()`` +method to perform an update or insert in a single operation. It also includes +example results in which it performs an insert. + +The following example shows how to perform an update or insert in a single +operation by passing the ``upsert`` option to the ``update()`` method. The +example output shows the result if the match criteria passed to the +``where()`` method matches zero documents in the collection. Click the +:guilabel:`VIEW OUTPUT` button to see the document inserted by running the +code: + +.. io-code-block:: + + .. input:: /includes/fundamentals/write-operations/WriteOperationsTest.php + :language: php + :dedent: + :start-after: begin model upsert + :end-before: end model upsert + + .. output:: json + + { + "_id": "660c...", + "performer": "Jon Batiste", + "venue": "Radio City Music Hall", + "genres": [ + "R&B", + "soul" + ], + "ticketsSold": 4000, + "updated_at": ... + } + diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index f45f6f3de..ac26e215d 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -226,4 +226,30 @@ public function testModelUpdateMultiple(): void $this->assertEquals(0, $result->ticketsSold); } } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testModelUpsert(): void + { + // + + require_once __DIR__ . '/Concert.php'; + Concert::truncate(); + + // begin model upsert + Concert::where(['performer' => 'Jon Batiste', 'venue' => 'Radio City Music Hall']) + ->update( + [ 'genres' => [ 'R&B', 'soul' ], 'ticketsSold' => 4000 ], + [ 'upsert' => true ] ); + // end model upsert + + $result = Concert::first(); + + print_r($result->toJson()); + $this->assertInstanceOf(Concert::class, $result); + $this->assertEquals('Jon Batiste', $result->performer); + $this->assertEquals(4000, $result->ticketsSold); + } } From dfe2019cc88cfc436427987634ca5d2ab2443fad Mon Sep 17 00:00:00 2001 From: ccho-mongodb Date: Tue, 2 Apr 2024 17:54:47 +0000 Subject: [PATCH 23/26] apply phpcbf formatting --- .../fundamentals/write-operations/WriteOperationsTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index ac26e215d..c82cffe6e 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -10,6 +10,7 @@ use MongoDB\Laravel\Tests\TestCase; use function count; +use function print_r; class WriteOperationsTest extends TestCase { @@ -241,8 +242,9 @@ public function testModelUpsert(): void // begin model upsert Concert::where(['performer' => 'Jon Batiste', 'venue' => 'Radio City Music Hall']) ->update( - [ 'genres' => [ 'R&B', 'soul' ], 'ticketsSold' => 4000 ], - [ 'upsert' => true ] ); + ['genres' => ['R&B', 'soul'], 'ticketsSold' => 4000], + ['upsert' => true], + ); // end model upsert $result = Concert::first(); From ebf1cc5e056501294d340bb8716d6e25bd9fa736 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Tue, 2 Apr 2024 13:58:20 -0400 Subject: [PATCH 24/26] fix io-codeblock --- docs/fundamentals/write-operations.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 625fcccd8..7b3ee6ede 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -302,7 +302,8 @@ code: :start-after: begin model upsert :end-before: end model upsert - .. output:: json + .. output:: + :language: json { "_id": "660c...", From 2c339bd9890b2d9e3903c2554f32b08241b40760 Mon Sep 17 00:00:00 2001 From: Chris Cho Date: Tue, 2 Apr 2024 14:38:29 -0400 Subject: [PATCH 25/26] tweaks --- docs/fundamentals/write-operations.txt | 16 ++++++++-------- .../write-operations/WriteOperationsTest.php | 3 +-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/fundamentals/write-operations.txt b/docs/fundamentals/write-operations.txt index 7b3ee6ede..633c1fd87 100644 --- a/docs/fundamentals/write-operations.txt +++ b/docs/fundamentals/write-operations.txt @@ -269,16 +269,15 @@ To specify an upsert in an ``update()`` method, set the ``upsert`` option to YourModel::where() ->update( [], - [upsert => true] - ); + [upsert => true]); -This operation performs one of the following actions: +When the ``update()`` method is chained to a query, it performs one of the +following actions: -- If the ``update()`` method is chained to a query that matches documents, - it updates the matching documents. -- If the ``update()`` method is chained to a query that matches zero documents, - it inserts a document that contains the update data and the equality match - criteria data. +- If the query matches documents, the ``update()`` method updates the matching + documents. +- If the query matches zero documents, the ``update()`` method inserts a + document that contains the update data and the equality match criteria data. Upsert Example ~~~~~~~~~~~~~~ @@ -304,6 +303,7 @@ code: .. output:: :language: json + :visible: false { "_id": "660c...", diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index c82cffe6e..1749acfb2 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -243,8 +243,7 @@ public function testModelUpsert(): void Concert::where(['performer' => 'Jon Batiste', 'venue' => 'Radio City Music Hall']) ->update( ['genres' => ['R&B', 'soul'], 'ticketsSold' => 4000], - ['upsert' => true], - ); + ['upsert' => true]); // end model upsert $result = Concert::first(); From f2b0412f7be6e82d021af445cb940f42c5bc3803 Mon Sep 17 00:00:00 2001 From: ccho-mongodb Date: Tue, 2 Apr 2024 18:40:27 +0000 Subject: [PATCH 26/26] apply phpcbf formatting --- .../fundamentals/write-operations/WriteOperationsTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php index 1749acfb2..c82cffe6e 100644 --- a/docs/includes/fundamentals/write-operations/WriteOperationsTest.php +++ b/docs/includes/fundamentals/write-operations/WriteOperationsTest.php @@ -243,7 +243,8 @@ public function testModelUpsert(): void Concert::where(['performer' => 'Jon Batiste', 'venue' => 'Radio City Music Hall']) ->update( ['genres' => ['R&B', 'soul'], 'ticketsSold' => 4000], - ['upsert' => true]); + ['upsert' => true], + ); // end model upsert $result = Concert::first();