Skip to content

Commit 44725c4

Browse files
committed
add model method
1 parent 5bbd07d commit 44725c4

File tree

3 files changed

+120
-7
lines changed

3 files changed

+120
-7
lines changed

docs/feature-compatibility.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ Eloquent Features
216216
- ✓
217217

218218
* - Upserts
219-
- ✓ See :ref:`laravel-mongodb-query-builder-upsert`.
219+
- ✓ See :ref:`laravel-modify-documents-upsert`.
220220

221221
* - Deleting Models
222222
- ✓

docs/fundamentals/write-operations.txt

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,86 @@ An **upsert** operation lets you perform an update or insert in a single
258258
operation. This operation streamlines the task of updating a document or
259259
inserting one if it does not exist.
260260

261+
Starting in v4.7, you can perform an upsert operation by using either of
262+
the following methods:
263+
264+
- Use the ``upsert()`` method. When you use this method,
265+
you can perform a **batch upsert** to change or insert multiple documents
266+
in one operation.
267+
268+
- Use the ``update()`` method and specify the ``upsert``
269+
option to update all documents that match the query filter or insert
270+
one document if no documents are matched. Only this method is
271+
supported in versions v4.6 and earlier.
272+
273+
Upsert Method
274+
~~~~~~~~~~~~~
275+
276+
The ``upsert()`` query builder method accepts the following parameters:
277+
278+
- Array of fields and values that specify documents to update or insert.
279+
- Array of fields that uniquely identify documents in your first array parameter.
280+
- Array of fields to update if a matching document exists. If you omit
281+
this parameter, {+odm-short+} updates all fields.
282+
283+
To specify an upsert in the ``upsert()`` method, set parameters
284+
as shown in the following code example:
285+
286+
.. code-block:: php
287+
:emphasize-lines: 4
288+
:copyable: false
289+
290+
YourModel::upsert(
291+
[/* documents to update or insert */],
292+
'/* unique field */', [/* fields to update */']
293+
);
294+
295+
Example
296+
^^^^^^^
297+
298+
This example shows how to use the ``upsert()``
299+
method to perform an update or insert in a single operation. Click the
300+
:guilabel:`{+code-output-label+}` button to see the resulting data changes if
301+
there is an ``'Angel Olson'`` document in the collection already:
302+
303+
.. io-code-block::
304+
305+
.. input:: /includes/fundamentals/write-operations/WriteOperationsTest.php
306+
:language: php
307+
:dedent:
308+
:start-after: begin model upsert
309+
:end-before: end model upsert
310+
311+
.. output::
312+
:language: json
313+
:visible: false
314+
315+
{
316+
"_id": "...",
317+
"performer": "Angel Olsen",
318+
"venue": "State Theatre",
319+
"genres": [
320+
"indie",
321+
"rock"
322+
],
323+
"ticketsSold": 275,
324+
"updated_at": ...
325+
},
326+
{
327+
"_id": "...",
328+
"performer": "Darondo",
329+
"venue": "Cafe du Nord",
330+
"ticketsSold": 300,
331+
"updated_at": ...
332+
}
333+
334+
In the ``'Angel Olsen'`` document, the ``venue`` field value is not
335+
changed, as the upsert specifies that the update only applies to the
336+
``ticketsSold`` field.
337+
338+
Update Method
339+
~~~~~~~~~~~~~
340+
261341
To specify an upsert in an ``update()`` method, set the ``upsert`` option to
262342
``true`` as shown in the following code example:
263343

@@ -278,8 +358,8 @@ following actions:
278358
- If the query matches zero documents, the ``update()`` method inserts a
279359
document that contains the update data and the equality match criteria data.
280360

281-
Upsert Example
282-
~~~~~~~~~~~~~~
361+
Example
362+
^^^^^^^
283363

284364
This example shows how to pass the ``upsert`` option to the ``update()``
285365
method to perform an update or insert in a single operation. Click the
@@ -291,8 +371,8 @@ matching documents exist:
291371
.. input:: /includes/fundamentals/write-operations/WriteOperationsTest.php
292372
:language: php
293373
:dedent:
294-
:start-after: begin model upsert
295-
:end-before: end model upsert
374+
:start-after: begin model update upsert
375+
:end-before: end model update upsert
296376

297377
.. output::
298378
:language: json

docs/includes/fundamentals/write-operations/WriteOperationsTest.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ public function testModelUpdateMultiple(): void
217217
}
218218
}
219219

220-
/**
220+
/**
221221
* @runInSeparateProcess
222222
* @preserveGlobalState disabled
223223
*/
@@ -226,13 +226,46 @@ public function testModelUpsert(): void
226226
require_once __DIR__ . '/Concert.php';
227227
Concert::truncate();
228228

229+
// Pre-existing sample document
230+
Concert::create([
231+
'performer' => 'Angel Olsen',
232+
'venue' => 'State Theatre',
233+
'genres' => [ 'indie', 'rock' ],
234+
'ticketsSold' => 150,
235+
]);
236+
229237
// begin model upsert
238+
Concert::upsert([
239+
['performer' => 'Angel Olsen', 'venue' => 'Academy of Music', 'ticketsSold' => 275],
240+
['performer' => 'Darondo', 'venue' => 'Cafe du Nord', 'ticketsSold' => 300],
241+
], 'performer', ['ticketsSold']);
242+
// end model upsert
243+
244+
$this->assertSame(2, Concert::count());
245+
246+
$this->assertSame(275, Concert::where('performer', 'Angel Olsen')->first()->ticketsSold);
247+
$this->assertSame('State Theatre', Concert::where('performer', 'Angel Olsen')->first()->venue);
248+
249+
$this->assertSame(300, Concert::where('performer', 'Darondo')->first()->ticketsSold);
250+
$this->assertSame('Cafe du Nord', Concert::where('performer', 'Darondo')->first()->venue);
251+
}
252+
253+
/**
254+
* @runInSeparateProcess
255+
* @preserveGlobalState disabled
256+
*/
257+
public function testModelUpdateUpsert(): void
258+
{
259+
require_once __DIR__ . '/Concert.php';
260+
Concert::truncate();
261+
262+
// begin model update upsert
230263
Concert::where(['performer' => 'Jon Batiste', 'venue' => 'Radio City Music Hall'])
231264
->update(
232265
['genres' => ['R&B', 'soul'], 'ticketsSold' => 4000],
233266
['upsert' => true],
234267
);
235-
// end model upsert
268+
// end model update upsert
236269

237270
$result = Concert::first();
238271

0 commit comments

Comments
 (0)