mongodb/laravel-mongodb · error · LogicException
Constraints on the embedded relation
Error message
Constraints on the embedded relation "%s" are not supported.
What it means
When using withAggregate/withCount/withSum etc. on an embedded relation (EmbedsOneOrMany), MongoDB Laravel cannot apply query constraints (where, limit, offset, distinct) to the embedded documents, because aggregates on embedded data are computed in PHP from the parent document, not by a server query. The library throws this LogicException as soon as any constraint closure passed to withAggregate adds one of those clauses.
Solutions
- Remove the where/limit/offset/distinct constraints from the closure for the embedded relation.
- Filter or limit the embedded documents after fetching, e.g. compute the aggregate manually from $model->relation and filter in PHP with collections.
- If filtering is essential, restructure so the data is stored in a separate collection with a HasOneOrMany/BelongsToMany relation, which supports constraints.
Example fix
// before
Order::withAggregate('lines:sum(total)', fn ($q) => $q->where('refunded', false))->get();
// after
Order::withAggregate('lines:sum(total)')->get()->each(function ($order) {
$order->lines_sum_total = collect($order->lines)->where('refunded', false)->sum('total');
}); Defensive patterns
Strategy: validation
Validate before calling
// Check the closure adds no constraints before calling withAggregate on an embedded relation
$q = $model->related()->getRelated()->newQuery();
$closure($q);
$base = $q->getQuery();
if ($base->wheres || $base->limit !== null || $base->offset !== null || $base->distinct) {
throw new LogicException('Constraints are not supported on embedded relation aggregates.');
} Type guard
function supportsEmbeddedConstraints($relation): bool {
return !($relation instanceof \MongoDB\Laravel\Relations\EmbedsOneOrMany);
} Try / catch
try {
$result = Order::withAggregate('lines:sum(total)', fn ($q) => $q->where('active', true))->get();
} catch (\LogicException $e) {
// fall back to computing the aggregate in PHP
$result = Order::withAggregate('lines:sum(total)')->get();
} Prevention
- Do not pass constraint closures when aggregating embedsMany/embedsOne relations.
- Filter embedded documents with Laravel collections after fetching the parent.
- Move heavily filtered aggregates to a separate collection with hasMany/belongsToMany relations.
When it happens
Trigger: Calling e.g. Model::withAggregate('embeddedItems:sum(price)', fn($q) => $q->where('active', true)) or withCount('embeds', fn($q) => $q->limit(5)) where the relation is an embedsMany/embedsOne and the closure applies where/limit/offset/distinct.
Common situations: Developers migrating from SQL-backed Eloquent where filtering sub-aggregates via closures works; they reuse the same constraint closures for embedded relations and hit the limitation since MongoDB embedded aggregates are computed client-side after reading the parent document.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Ordering by the aggregated field
- The relation key of type
- Aggregating the hybrid relation
- is not supported for relation aggregates.
- Parent model must be a document model.
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/7238cc3ded0f870c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Helpers/QueriesRelationshipAggregates.php:139
'',
sprintf('%s %s %s', $name, $function, strtolower($column)),
));
return [$name, $alias];
}
private function assertEmbeddedConstraintsSupported(Relation $relation, string $name, Closure $constraints): void
{
if (! $relation instanceof EmbedsOneOrMany) {
return;
}
$subQuery = $relation->getRelated()->newQuery();
$constraints($subQuery);
$query = $subQuery->getQuery();
if ($query->wheres || $query->limit !== null || $query->offset !== null || $query->distinct) {
throw new LogicException(sprintf(
'Constraints on the embedded relation "%s" are not supported.',
$name,
));
}
}
/** @inheritdoc */
public function eagerLoadRelations(array $models)
{
foreach ($this->withAggregates as $alias => $aggregate) {
$this->assertAggregateNotUsedInQuery($alias);
$this->hydrateAggregate($models, $alias, $aggregate);
}
return parent::eagerLoadRelations($models);
}
/**View on GitHub (pinned to 0634653039)