Skip to content

Commit 99ca385

Browse files
committed
DOCSP-41621: upsert
1 parent 432456b commit 99ca385

File tree

4 files changed

+127
-66
lines changed

4 files changed

+127
-66
lines changed

docs/feature-compatibility.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ The following Eloquent methods are not supported in {+odm-short+}:
151151
- *Unsupported as MongoDB uses ObjectIDs*
152152

153153
* - Upserts
154-
- *Unsupported*
154+
- ✓ See :ref:`laravel-upsert`.
155155

156156
* - Update Statements
157157
- ✓
@@ -216,7 +216,7 @@ Eloquent Features
216216
- ✓
217217

218218
* - Upserts
219-
- *Unsupported, but you can use the createOneOrFirst() method*
219+
- ✓ See :ref:`laravel-upsert`.
220220

221221
* - Deleting Models
222222
- ✓

docs/includes/query-builder/QueryBuilderTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,26 @@ function (Collection $collection) {
506506
public function testUpsert(): void
507507
{
508508
// begin upsert
509+
$result = DB::collection('movies')
510+
->upsert(
511+
[
512+
['title' => 'Inspector Maigret', 'recommended' => 'false', 'runtime' => '128'],
513+
['title' => 'Petit Maman', 'recommended' => 'true', 'runtime' => '72'],
514+
],
515+
'title',
516+
'runtime'
517+
);
518+
// end upsert
519+
520+
$this->assertSame(2, $result);
521+
$this->assertSame(119, DB::collection('movies')->where('title', 'Inspector Maigret')->first()['runtime']);
522+
$this->assertSame(true, DB::collection('movies')->where('title', 'Petit Maman')->first()['recommended']);
523+
$this->assertSame(72, DB::collection('movies')->where('title', 'Petit Maman')->first()['runtime']);
524+
}
525+
526+
public function testUpdateUpsert(): void
527+
{
528+
// begin update upsert
509529
$result = DB::collection('movies')
510530
->where('title', 'Will Hunting')
511531
->update(
@@ -516,7 +536,7 @@ public function testUpsert(): void
516536
],
517537
['upsert' => true],
518538
);
519-
// end upsert
539+
// end update upsert
520540

521541
$this->assertIsInt($result);
522542
}

docs/includes/query-builder/sample_mflix.movies.json

Lines changed: 56 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
[
22
{
3-
"genres": [
4-
"Short"
5-
],
3+
"genres": ["Short"],
64
"runtime": 1,
7-
"cast": [
8-
"Charles Kayser",
9-
"John Ott"
10-
],
5+
"cast": ["Charles Kayser", "John Ott"],
116
"title": "Blacksmith Scene",
12-
"directors": [
13-
"William K.L. Dickson"
14-
],
7+
"directors": ["William K.L. Dickson"],
158
"rated": "UNRATED",
169
"year": 1893,
1710
"imdb": {
@@ -28,10 +21,7 @@
2821
}
2922
},
3023
{
31-
"genres": [
32-
"Short",
33-
"Western"
34-
],
24+
"genres": ["Short", "Western"],
3525
"runtime": 11,
3626
"cast": [
3727
"A.C. Abadie",
@@ -40,9 +30,7 @@
4030
"Justus D. Barnes"
4131
],
4232
"title": "The Great Train Robbery",
43-
"directors": [
44-
"Edwin S. Porter"
45-
],
33+
"directors": ["Edwin S. Porter"],
4634
"rated": "TV-G",
4735
"year": 1903,
4836
"imdb": {
@@ -59,11 +47,7 @@
5947
}
6048
},
6149
{
62-
"genres": [
63-
"Short",
64-
"Drama",
65-
"Fantasy"
66-
],
50+
"genres": ["Short", "Drama", "Fantasy"],
6751
"runtime": 14,
6852
"rated": "UNRATED",
6953
"cast": [
@@ -73,12 +57,8 @@
7357
"Ethel Jewett"
7458
],
7559
"title": "The Land Beyond the Sunset",
76-
"directors": [
77-
"Harold M. Shaw"
78-
],
79-
"writers": [
80-
"Dorothy G. Shore"
81-
],
60+
"directors": ["Harold M. Shaw"],
61+
"writers": ["Dorothy G. Shore"],
8262
"year": 1912,
8363
"imdb": {
8464
"rating": 7.1,
@@ -94,10 +74,7 @@
9474
}
9575
},
9676
{
97-
"genres": [
98-
"Short",
99-
"Drama"
100-
],
77+
"genres": ["Short", "Drama"],
10178
"runtime": 14,
10279
"cast": [
10380
"Frank Powell",
@@ -106,9 +83,7 @@
10683
"Linda Arvidson"
10784
],
10885
"title": "A Corner in Wheat",
109-
"directors": [
110-
"D.W. Griffith"
111-
],
86+
"directors": ["D.W. Griffith"],
11287
"rated": "G",
11388
"year": 1909,
11489
"imdb": {
@@ -125,20 +100,11 @@
125100
}
126101
},
127102
{
128-
"genres": [
129-
"Animation",
130-
"Short",
131-
"Comedy"
132-
],
103+
"genres": ["Animation", "Short", "Comedy"],
133104
"runtime": 7,
134-
"cast": [
135-
"Winsor McCay"
136-
],
105+
"cast": ["Winsor McCay"],
137106
"title": "Winsor McCay, the Famous Cartoonist of the N.Y. Herald and His Moving Comics",
138-
"directors": [
139-
"Winsor McCay",
140-
"J. Stuart Blackton"
141-
],
107+
"directors": ["Winsor McCay", "J. Stuart Blackton"],
142108
"writers": [
143109
"Winsor McCay (comic strip \"Little Nemo in Slumberland\")",
144110
"Winsor McCay (screenplay)"
@@ -158,22 +124,11 @@
158124
}
159125
},
160126
{
161-
"genres": [
162-
"Comedy",
163-
"Fantasy",
164-
"Romance"
165-
],
127+
"genres": ["Comedy", "Fantasy", "Romance"],
166128
"runtime": 118,
167-
"cast": [
168-
"Meg Ryan",
169-
"Hugh Jackman",
170-
"Liev Schreiber",
171-
"Breckin Meyer"
172-
],
129+
"cast": ["Meg Ryan", "Hugh Jackman", "Liev Schreiber", "Breckin Meyer"],
173130
"title": "Kate & Leopold",
174-
"directors": [
175-
"James Mangold"
176-
],
131+
"directors": ["James Mangold"],
177132
"writers": [
178133
"Steven Rogers (story)",
179134
"James Mangold (screenplay)",
@@ -192,5 +147,45 @@
192147
"meter": 62
193148
}
194149
}
150+
},
151+
{
152+
"genres": ["Crime", "Drama"],
153+
"runtime": 119,
154+
"cast": [
155+
"Jean Gabin",
156+
"Annie Girardot",
157+
"Olivier Hussenot",
158+
"Jeanne Boitel"
159+
],
160+
"title": "Inspector Maigret",
161+
"directors": ["Jean Delannoy"],
162+
"writers": [
163+
"Georges Simenon (novel)",
164+
"Jean Delannoy (adaptation)",
165+
"Rodolphe-Maurice Arlaud (adaptation)",
166+
"Michel Audiard (adaptation)",
167+
"Michel Audiard (dialogue)"
168+
],
169+
"year": 1958,
170+
"imdb": {
171+
"rating": 7.1,
172+
"votes": 690,
173+
"id": 50669
174+
},
175+
"countries": ["France", "Italy"],
176+
"type": "movie",
177+
"tomatoes": {
178+
"viewer": {
179+
"rating": 2.7,
180+
"numReviews": 77,
181+
"meter": 14
182+
},
183+
"dvd": {
184+
"$date": "2007-01-23T00:00:00.000Z"
185+
},
186+
"lastUpdated": {
187+
"$date": "2015-09-14T22:31:29.000Z"
188+
}
189+
}
195190
}
196191
]

docs/query-builder.txt

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,52 @@ following MongoDB-specific write operations:
10351035
Upsert a Document Example
10361036
~~~~~~~~~~~~~~~~~~~~~~~~~
10371037

1038+
You can perform an upsert operation by taking either of the following
1039+
actions:
1040+
1041+
- Use the ``upsert()`` query builder method. When you use this method,
1042+
you can perform a batch upsert to change or insert multiple documents
1043+
in one operation.
1044+
- Use the ``update()`` query builder method and specify the ``upsert`` option.
1045+
1046+
Upsert Method
1047+
`````````````
1048+
1049+
The ``upsert()`` query builder method accepts the following parameters:
1050+
1051+
- Array of fields and values that specify documents to update or insert.
1052+
- Array of fields that uniquely identify documents in your first array parameter.
1053+
- Array of fields to update if a matching document exists. If you omit
1054+
this parameter, {+odm-short+} updates all fields.
1055+
1056+
The following example shows how to use the ``upsert()`` query builder method
1057+
to update or insert documents based on the following instructions:
1058+
1059+
- Specify a document in which the value of the ``title`` field is
1060+
``'Inspector Maigret'``, the value of the ``recommended`` field is ``false``,
1061+
and the value of the ``runtime`` field is ``128``.
1062+
1063+
- Specify a document in which the value of the ``title`` field is
1064+
``'Petit Maman'``, the value of the ``recommended`` field is
1065+
``true``, and the value of the ``runtime`` field is ``72``.
1066+
1067+
- Indicate that the ``title`` field uniquely identifies documents in the
1068+
scope of your operation.
1069+
1070+
- Update only the ``runtime`` field in matched documents.
1071+
1072+
.. literalinclude:: /includes/query-builder/QueryBuilderTest.php
1073+
:language: php
1074+
:dedent:
1075+
:start-after: begin upsert
1076+
:end-before: end upsert
1077+
1078+
The ``upsert()`` query builder method returns the sum of the number of documents that the
1079+
operation updated, inserted, and modified.
1080+
1081+
Update Method
1082+
`````````````
1083+
10381084
The following example shows how to use the ``update()`` query builder method
10391085
and ``upsert`` option to update the matching document or insert one with the
10401086
specified data if it does not exist. When you set the ``upsert`` option to
@@ -1044,8 +1090,8 @@ and the ``title`` field and value specified in the ``where()`` query operation:
10441090
.. literalinclude:: /includes/query-builder/QueryBuilderTest.php
10451091
:language: php
10461092
:dedent:
1047-
:start-after: begin upsert
1048-
:end-before: end upsert
1093+
:start-after: begin update upsert
1094+
:end-before: end update upsert
10491095

10501096
The ``update()`` query builder method returns the number of documents that the
10511097
operation updated or inserted.

0 commit comments

Comments
 (0)