fix: count() after groupBy() returns integer instead of Collection#3513
Draft
GromNaN wants to merge 1 commit into
Draft
fix: count() after groupBy() returns integer instead of Collection#3513GromNaN wants to merge 1 commit into
GromNaN wants to merge 1 commit into
Conversation
When count() was called on a query with groupBy(), the aggregate() method returned a Collection of per-group results instead of a scalar. Laravel's count() casts the return value to int, causing a PHP warning and always returning 1. Override count() to use a $match + $group + $count aggregation pipeline when groups are present, returning the number of distinct groups. This mirrors the pattern used in runPaginationCountQuery(). Fixes mongodb#3512
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
count()inQuery\Builderto handlegroupBy()correctly$match+$group+$countaggregation pipeline to return the number of distinct groups as an integerrunPaginationCountQuery()Problem
->groupBy('status')->count()triggered a PHP warning and returned1:The root cause:
aggregate()returns aCollectionwhen$this->groupsis set, butcount()casts the return value to(int).Note on SQL behavior
For reference, Eloquent SQL generates
SELECT count(*) as aggregate FROM ... GROUP BY status, which returns one row per group. Laravel takes$results[0]['aggregate'], i.e. the count of the first (arbitrary) group — not the number of groups, and not the total count.Our implementation returns the number of distinct groups, which is consistent with
runPaginationCountQuery()behavior and more predictable than the SQL equivalent.Test plan
testCountWithGroupBycovers the fix (multiple groups, filtered result, no match)testAggregateGroupByconfirmsaggregateByGroup('count')still returns per-group Collection unchanged