Skip to content

Commit 7880990

Browse files
authored
PHPORM-90 Fix whereNot to use $nor (#2624)
1 parent c112ef7 commit 7880990

File tree

3 files changed

+79
-26
lines changed

3 files changed

+79
-26
lines changed

src/Query/Builder.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,8 +1053,9 @@ protected function compileWheres(): array
10531053
$method = 'compileWhere' . $where['type'];
10541054
$result = $this->{$method}($where);
10551055

1056+
// Negate the expression
10561057
if (str_ends_with($where['boolean'], 'not')) {
1057-
$result = ['$not' => $result];
1058+
$result = ['$nor' => [$result]];
10581059
}
10591060

10601061
// Wrap the where with an $or operator.

tests/Query/BuilderTest.php

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ public static function provideQueryBuilderToMql(): iterable
195195
'find' => [
196196
[
197197
'$and' => [
198-
['$not' => ['name' => 'foo']],
199-
['$not' => ['name' => ['$ne' => 'bar']]],
198+
['$nor' => [['name' => 'foo']]],
199+
['$nor' => [['name' => ['$ne' => 'bar']]]],
200200
],
201201
],
202202
[], // options
@@ -231,8 +231,8 @@ public static function provideQueryBuilderToMql(): iterable
231231
'find' => [
232232
[
233233
'$or' => [
234-
['$not' => ['name' => 'foo']],
235-
['$not' => ['name' => ['$ne' => 'bar']]],
234+
['$nor' => [['name' => 'foo']]],
235+
['$nor' => [['name' => ['$ne' => 'bar']]]],
236236
],
237237
],
238238
[], // options
@@ -248,7 +248,7 @@ public static function provideQueryBuilderToMql(): iterable
248248
'find' => [
249249
[
250250
'$or' => [
251-
['$not' => ['name' => 'foo']],
251+
['$nor' => [['name' => 'foo']]],
252252
['name' => ['$ne' => 'bar']],
253253
],
254254
],
@@ -264,7 +264,7 @@ public static function provideQueryBuilderToMql(): iterable
264264
yield 'whereNot callable' => [
265265
[
266266
'find' => [
267-
['$not' => ['name' => 'foo']],
267+
['$nor' => [['name' => 'foo']]],
268268
[], // options
269269
],
270270
],
@@ -278,7 +278,7 @@ public static function provideQueryBuilderToMql(): iterable
278278
[
279279
'$and' => [
280280
['name' => 'bar'],
281-
['$not' => ['email' => 'foo']],
281+
['$nor' => [['email' => 'foo']]],
282282
],
283283
],
284284
[], // options
@@ -295,10 +295,12 @@ public static function provideQueryBuilderToMql(): iterable
295295
[
296296
'find' => [
297297
[
298-
'$not' => [
299-
'$and' => [
300-
['name' => 'foo'],
301-
['$not' => ['email' => ['$ne' => 'bar']]],
298+
'$nor' => [
299+
[
300+
'$and' => [
301+
['name' => 'foo'],
302+
['$nor' => [['email' => ['$ne' => 'bar']]]],
303+
],
302304
],
303305
],
304306
],
@@ -318,7 +320,7 @@ public static function provideQueryBuilderToMql(): iterable
318320
[
319321
'$or' => [
320322
['name' => 'bar'],
321-
['$not' => ['email' => 'foo']],
323+
['$nor' => [['email' => 'foo']]],
322324
],
323325
],
324326
[], // options
@@ -337,7 +339,7 @@ public static function provideQueryBuilderToMql(): iterable
337339
[
338340
'$or' => [
339341
['name' => 'bar'],
340-
['$not' => ['email' => 'foo']],
342+
['$nor' => [['email' => 'foo']]],
341343
],
342344
],
343345
[], // options
@@ -353,10 +355,12 @@ public static function provideQueryBuilderToMql(): iterable
353355
[
354356
'find' => [
355357
[
356-
'$not' => [
357-
'$and' => [
358-
['foo' => 1],
359-
['bar' => 2],
358+
'$nor' => [
359+
[
360+
'$and' => [
361+
['foo' => 1],
362+
['bar' => 2],
363+
],
360364
],
361365
],
362366
],
@@ -371,10 +375,12 @@ public static function provideQueryBuilderToMql(): iterable
371375
[
372376
'find' => [
373377
[
374-
'$not' => [
375-
'$and' => [
376-
['foo' => 1],
377-
['bar' => 2],
378+
'$nor' => [
379+
[
380+
'$and' => [
381+
['foo' => 1],
382+
['bar' => 2],
383+
],
378384
],
379385
],
380386
],
@@ -389,10 +395,12 @@ public static function provideQueryBuilderToMql(): iterable
389395
[
390396
'find' => [
391397
[
392-
'$not' => [
393-
'$and' => [
394-
['foo' => 1],
395-
['bar' => ['$lt' => 2]],
398+
'$nor' => [
399+
[
400+
'$and' => [
401+
['foo' => 1],
402+
['bar' => ['$lt' => 2]],
403+
],
396404
],
397405
],
398406
],

tests/QueryTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use DateTimeImmutable;
88
use LogicException;
9+
use MongoDB\BSON\Regex;
10+
use MongoDB\Laravel\Eloquent\Builder;
911
use MongoDB\Laravel\Tests\Models\Birthday;
1012
use MongoDB\Laravel\Tests\Models\Scoped;
1113
use MongoDB\Laravel\Tests\Models\User;
@@ -154,6 +156,48 @@ public function testSelect(): void
154156
$this->assertNull($user->age);
155157
}
156158

159+
public function testWhereNot(): void
160+
{
161+
// implicit equality operator
162+
$users = User::whereNot('title', 'admin')->get();
163+
$this->assertCount(6, $users);
164+
165+
// nested query
166+
$users = User::whereNot(fn (Builder $builder) => $builder->where('title', 'admin'))->get();
167+
$this->assertCount(6, $users);
168+
169+
// double negation
170+
$users = User::whereNot('title', '!=', 'admin')->get();
171+
$this->assertCount(3, $users);
172+
173+
// nested negation
174+
$users = User::whereNot(fn (Builder $builder) => $builder
175+
->whereNot('title', 'admin'))->get();
176+
$this->assertCount(3, $users);
177+
178+
// explicit equality operator
179+
$users = User::whereNot('title', '=', 'admin')->get();
180+
$this->assertCount(6, $users);
181+
182+
// custom query operator
183+
$users = User::whereNot('title', ['$in' => ['admin']])->get();
184+
$this->assertCount(6, $users);
185+
186+
// regex
187+
$users = User::whereNot('title', new Regex('^admin$'))->get();
188+
$this->assertCount(6, $users);
189+
190+
// equals null
191+
$users = User::whereNot('title', null)->get();
192+
$this->assertCount(8, $users);
193+
194+
// nested $or
195+
$users = User::whereNot(fn (Builder $builder) => $builder
196+
->where('title', 'admin')
197+
->orWhere('age', 35))->get();
198+
$this->assertCount(5, $users);
199+
}
200+
157201
public function testOrWhere(): void
158202
{
159203
$users = User::where('age', 13)->orWhere('title', 'admin')->get();

0 commit comments

Comments
 (0)