Skip to content

Commit 589e329

Browse files
authored
Merge pull request #26 from utopia-php/refactor-count
Add test for count method in MongoDB integration
2 parents e21c600 + 2138409 commit 589e329

2 files changed

Lines changed: 117 additions & 3 deletions

File tree

src/Client.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,10 +720,35 @@ public function delete(string $collection, array $filters = [], int $limit = 1,
720720
*/
721721
public function count(string $collection, array $filters, array $options): int
722722
{
723-
$result = $this->find($collection, $filters, $options);
724-
$list = $result->cursor->firstBatch;
723+
$filters = $this->cleanFilters($filters);
724+
725+
// Use MongoDB's native count command with the working format instad of running find and count the results
726+
$command = [
727+
self::COMMAND_COUNT => $collection,
728+
'query' => $this->toObject($filters),
729+
];
725730

726-
return \count($list);
731+
// Add limit if specified
732+
if (isset($options['limit'])) {
733+
$command['limit'] = (int)$options['limit'];
734+
}
735+
736+
// Add skip if specified
737+
if (isset($options['skip'])) {
738+
$command['skip'] = (int)$options['skip'];
739+
}
740+
741+
// Add maxTimeMS if specified
742+
if (isset($options['maxTimeMS'])) {
743+
$command['maxTimeMS'] = (int)$options['maxTimeMS'];
744+
}
745+
746+
try {
747+
$result = $this->query($command);
748+
return (int)$result;
749+
} catch (Exception $e) {
750+
return 0;
751+
}
727752
}
728753

729754
/**

tests/MongoTest.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,93 @@ public function testUpsert()
261261
self::assertEquals('USA', $documents[1]->country);
262262
self::assertEquals('English', $documents[1]->language);
263263
}
264+
265+
public function testCountMethod()
266+
{
267+
$collectionName = 'count_test';
268+
$this->getDatabase()->createCollection($collectionName);
269+
try {
270+
$documents = [];
271+
for ($i = 1; $i <= 30; $i++) {
272+
$documents[] = [
273+
'name' => "Document {$i}",
274+
'number' => $i,
275+
'category' => 'test',
276+
'created_at' => new \DateTime()
277+
];
278+
}
279+
280+
$this->getDatabase()->insertMany($collectionName, $documents);
281+
282+
$total = $this->getDatabase()->count($collectionName, [], []);
283+
self::assertEquals(30, $total);
284+
285+
// Test count with filter (should be 1 for each specific number)
286+
$total = $this->getDatabase()->count($collectionName, ['number' => 15], []);
287+
self::assertEquals(1, $total);
288+
289+
// Test count with range filter (should be 10 for numbers 1-10)
290+
$total = $this->getDatabase()->count($collectionName, ['number' => ['$lte' => 10]], []);
291+
self::assertEquals(10, $total);
292+
293+
// Test count with limit (should be 5 for first 5 documents)
294+
$total = $this->getDatabase()->count($collectionName, [], ['limit' => 5]);
295+
self::assertEquals(5, $total);
296+
297+
// Test count with filter and limit (should be 3 for first 3 documents with number <= 10)
298+
$total = $this->getDatabase()->count($collectionName, ['number' => ['$lte' => 10]], ['limit' => 3]);
299+
self::assertEquals(3, $total);
300+
301+
302+
// Test count with $or operator and comparison (should be 2 documents with number <= 2 OR number >= 29)
303+
$total = $this->getDatabase()->count($collectionName, ['$or' => [['number' => ['$lte' => 2]], ['number' => ['$gte' => 29]]]], []);
304+
self::assertEquals(4, $total);
305+
306+
// Test aggregation count - total documents
307+
$aggregationResult = $this->getDatabase()->aggregate($collectionName, [
308+
['$count' => 'total']
309+
]);
310+
self::assertEquals(30, $aggregationResult->cursor->firstBatch[0]->total);
311+
312+
// Test aggregation count with filter
313+
$filteredAggregationResult = $this->getDatabase()->aggregate($collectionName, [
314+
['$match' => ['number' => ['$lte' => 10]]],
315+
['$count' => 'total']
316+
]);
317+
self::assertEquals(10, $filteredAggregationResult->cursor->firstBatch[0]->total);
318+
319+
// Test aggregation count with limit
320+
$limitedAggregationResult = $this->getDatabase()->aggregate($collectionName, [
321+
['$limit' => 7],
322+
['$count' => 'total']
323+
]);
324+
self::assertEquals(7, $limitedAggregationResult->cursor->firstBatch[0]->total);
325+
326+
// Test aggregation count with group by
327+
$groupedAggregationResult = $this->getDatabase()->aggregate($collectionName, [
328+
['$group' => [
329+
'_id' => '$category', // Group by category
330+
'count' => ['$sum' => 1] // Count of documents in the group
331+
]]
332+
]);
333+
self::assertEquals(30, $groupedAggregationResult->cursor->firstBatch[0]->count);
334+
self::assertEquals('test', $groupedAggregationResult->cursor->firstBatch[0]->_id);
335+
336+
// Test aggregation count with $or operator
337+
$orAggregationResult = $this->getDatabase()->aggregate($collectionName, [
338+
['$match' => ['$or' => [['number' => 5], ['number' => 15], ['number' => 25]]]],
339+
['$count' => 'total']
340+
]);
341+
self::assertEquals(3, $orAggregationResult->cursor->firstBatch[0]->total);
342+
343+
// Test aggregation count with complex $or and range
344+
$complexOrAggregationResult = $this->getDatabase()->aggregate($collectionName, [
345+
['$match' => ['$or' => [['number' => ['$lte' => 3]], ['number' => ['$gte' => 28]]]]],
346+
['$count' => 'total']
347+
]);
348+
self::assertEquals(6, $complexOrAggregationResult->cursor->firstBatch[0]->total);
349+
} finally {
350+
$this->getDatabase()->dropCollection($collectionName);
351+
}
352+
}
264353
}

0 commit comments

Comments
 (0)