Queries & statistics.
Install the open-source review engine, connect a model, and build your own review experience.
← All Core topicsQueries and statistics
Core returns approved reviews by default. Request pending reviews only from an authorized private workflow.
$published = $product->getReviews();
$pending = $product->getReviews(false);
$withoutRatings = $product->getReviews(true, false);
$supportReviews = $product->getReviewsByDepartment('support');
$fiveStarReviews = $product->getReviewsByRating(
5, department: 'support'
);
$total = $product->totalReviews();
$supportTotal = $product->totalDepartmentReviews('support');
$overall = $product->averageRating('overall');
$averages = $product->averageRatings();
$supportAverage = $product->averageRatingByDepartment('support', 'overall');
$allCriteriaAverage = $product->overallAverageRating();
$distribution = $product->ratingCounts('default');
$stats = $product->ratingStats('default');
$overallDistribution = $product->ratingCountsForKey('overall', 'default');
$overallStats = $product->ratingStatsForKey('overall', 'default');
$fiveStarOverallReviews = $product->getReviewsByRatingForKey(5, 'overall', 'default');
The ForKey methods require Core 2.3.0 or later. They are available on the model trait and through the injectable CriterionRatingContract after setModel($product); the original ReviewRateableContract stays unchanged. ratingStats() and ratingStatsForKey() return counts, percentages, and total. The existing ratingCounts(), ratingStats(), and getReviewsByRating() methods retain their all-criteria behavior: they count rating rows or match a review when any criterion has the requested value. The new ForKey methods restrict those results to one stored rating key. They still count approved reviews by default; pass approved: false only in an authorized private workflow. Pass null as the department to count one key across all departments. No migration is required.
Pro selects a headline criterion for each department's summary and filters using listing.summary_rating_key and optional department overrides in listing.summary_rating_keys.
Use the relationship for pagination, eager loading, or custom criteria:
$reviews = $product->reviews()
->where('department', 'default')
->where('approved', true)
->whereHas('ratings', fn ($query) => $query
->where('key', 'overall')
->where('value', 5))
->with(['ratings', 'user'])
->latest()
->paginate(10);
Only eager-load optional relationships after installing their tables. Avoid unapproved content in public JSON, caches, or summaries.