Skip to content

Commit d46dcdd

Browse files
committed
Implement Query\Builder::insertOrIgnore()
1 parent e955aaf commit d46dcdd

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
66
* New aggregation pipeline builder by @GromNaN in [#2738](https://github.com/mongodb/laravel-mongodb/pull/2738)
77
* Drop support for Composer 1.x by @GromNaN in [#2784](https://github.com/mongodb/laravel-mongodb/pull/2784)
88
* Fix `artisan query:retry` command by @GromNaN in [#2838](https://github.com/mongodb/laravel-mongodb/pull/2838)
9+
* Implement `MongoDB\Laravel\Query\Builder::insertOrIgnore()` to ignore duplicate values
910

1011
## [4.2.0] - 2024-03-14
1112

src/Query/Builder.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use MongoDB\BSON\UTCDateTime;
2424
use MongoDB\Builder\Stage\FluentFactoryTrait;
2525
use MongoDB\Driver\Cursor;
26+
use MongoDB\Driver\Exception\BulkWriteException;
2627
use Override;
2728
use RuntimeException;
2829

@@ -659,6 +660,26 @@ public function whereBetween($column, iterable $values, $boolean = 'and', $not =
659660

660661
/** @inheritdoc */
661662
public function insert(array $values)
663+
{
664+
return $this->performInsert($values);
665+
}
666+
667+
/** @inheritdoc */
668+
public function insertOrIgnore(array $values)
669+
{
670+
try {
671+
return $this->performInsert($values, ['ordered' => false]);
672+
} catch (BulkWriteException $exception) {
673+
// Ignore "duplicate key error"
674+
if ($exception->getCode() !== 11000) {
675+
throw $exception;
676+
}
677+
678+
return $exception->getWriteResult()->isAcknowledged();
679+
}
680+
}
681+
682+
private function performInsert(array $values, array $options = [])
662683
{
663684
// Allow empty insert batch for consistency with Eloquent SQL
664685
if ($values === []) {
@@ -682,7 +703,7 @@ public function insert(array $values)
682703
$values = [$values];
683704
}
684705

685-
$options = $this->inheritConnectionOptions();
706+
$options += $this->inheritConnectionOptions();
686707

687708
$result = $this->collection->insertMany($values, $options);
688709

tests/QueryBuilderTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ public function testBatchInsert()
142142
$this->assertIsArray($users[0]['tags']);
143143
}
144144

145+
public function testInsertOrIgnoreMethod()
146+
{
147+
$builder = DB::collection('users');
148+
// Expect "duplicate key error" on _id field to be ignored
149+
$id = new ObjectId();
150+
$this->assertTrue($builder->insertOrIgnore(['_id' => $id]));
151+
$this->assertTrue($builder->insertOrIgnore(['_id' => $id]));
152+
$this->assertTrue($builder->insertOrIgnore([['_id' => $id], ['foo' => 'bar']]));
153+
$this->assertSame(2, $builder->count());
154+
}
155+
145156
public function testFind()
146157
{
147158
$id = DB::collection('users')->insertGetId(['name' => 'John Doe']);

0 commit comments

Comments
 (0)