Skip to content

Commit

Permalink
feat(Firestore): add query operator NOT_IN (#6111)
Browse files Browse the repository at this point in the history
  • Loading branch information
vishwarajanand authored Apr 25, 2023
1 parent b354020 commit fa1e622
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
5 changes: 3 additions & 2 deletions Firestore/src/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class Query
'array-contains' => FieldFilterOperator::ARRAY_CONTAINS,
'array-contains-any' => FieldFilterOperator::ARRAY_CONTAINS_ANY,
'in' => FieldFilterOperator::IN,
'not_in' => FieldFilterOperator::NOT_IN,
];

private $allowedDirections = [
Expand Down Expand Up @@ -1024,7 +1025,7 @@ private function createFieldFilter($fieldPath, $operator, $value)
}

if ($escapedPathString === self::DOCUMENT_ID) {
if ($operator === FieldFilterOperator::IN) {
if ($operator === FieldFilterOperator::IN || $operator === FieldFilterOperator::NOT_IN) {
$value = array_map(function ($value) use ($basePath) {
return $this->createDocumentReference($basePath, $value);
}, (array) $value);
Expand All @@ -1051,7 +1052,7 @@ private function createFieldFilter($fieldPath, $operator, $value)
]
];
} else {
$encodedValue = $operator === FieldFilterOperator::IN
$encodedValue = ($operator === FieldFilterOperator::IN || $operator === FieldFilterOperator::NOT_IN)
? $this->valueMapper->encodeMultiValue((array)$value)
: $this->valueMapper->encodeValue($value);

Expand Down
71 changes: 71 additions & 0 deletions Firestore/tests/System/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,77 @@ public function testWhereInArray()
$this->assertContains($doc2->id(), $doc_ids);
}

public function testWhereNotInArray()
{
$name = $this->query->name();
$doc1 = $this->insertDoc([
'foos' => ['foo', 'bar'],
]);
$doc2 = $this->insertDoc([
'foos' => ['foo'],
]);

$docs = self::$client->collection($name)->where('foos', 'not_in', [['foo']])->documents()->rows();
$this->assertCount(1, $docs);
$this->assertEquals($doc1->name(), $docs[0]->name());

$docs = self::$client->collection($name)->where('foos', 'not_in', [['foo'], ['foo', 'bar']])
->documents()->rows();
$this->assertEmpty($docs);

$docs = self::$client->collection($name)->where('foos', 'not_in', [['foo', 'bar']])->documents()->rows();
$this->assertCount(1, $docs);
$this->assertEquals($doc2->name(), $docs[0]->name());

$docs = self::$client->collection($name)
->where(FieldPath::documentId(), 'not_in', [$doc1->id(), $doc2->id()])
->documents()
->rows();
$this->assertEmpty($docs);

$docs = self::$client->collection($name)
->where(FieldPath::documentId(), 'not_in', ['non-existent-id'])
->documents()
->rows();
$this->assertCount(2, $docs);
$doc_ids = array_map(function ($doc) {
return $doc->id();
}, $docs);
$this->assertContains($doc1->id(), $doc_ids);
$this->assertContains($doc2->id(), $doc_ids);

$docs = self::$client->collection($name)
->where(Filter::field('foos', 'not_in', [['foo']]))->documents()->rows();
$this->assertCount(1, $docs);
$this->assertEquals($doc1->name(), $docs[0]->name());

$docs = self::$client->collection($name)
->where(Filter::field('foos', 'not_in', [['foo'], ['foo', 'bar']]))->documents()->rows();
$this->assertEmpty($docs);

$docs = self::$client->collection($name)
->where(Filter::field('foos', 'not_in', [['foo', 'bar']]))->documents()->rows();
$this->assertCount(1, $docs);
$this->assertEquals($doc2->name(), $docs[0]->name());

$docs = self::$client->collection($name)
->where(Filter::field(FieldPath::documentId(), 'not_in', [$doc1->id(), $doc2->id()]))
->documents()
->rows();
$this->assertEmpty($docs);

$docs = self::$client->collection($name)
->where(Filter::field(FieldPath::documentId(), 'not_in', ['non-existent-id']))
->documents()
->rows();
$this->assertCount(2, $docs);
$doc_ids = array_map(function ($doc) {
return $doc->id();
}, $docs);
$this->assertContains($doc1->id(), $doc_ids);
$this->assertContains($doc2->id(), $doc_ids);
}

public function testWhereWithCompositeFilter()
{
$name = $this->query->name();
Expand Down
2 changes: 2 additions & 0 deletions Firestore/tests/Unit/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,8 @@ public function whereOperators()
['array-contains'],
['in'],
['IN'],
['not_in'],
['NOT_IN'],
['array-contains-any'],
]);
}
Expand Down

0 comments on commit fa1e622

Please sign in to comment.