-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PHPORM-155 Fluent aggregation builder #2738
Conversation
c1450e2
to
a2859a6
Compare
src/Eloquent/Builder.php
Outdated
{ | ||
$result = $this->toBase()->aggregate($function, $columns); | ||
|
||
return $result ?? $this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method must be overrided, because by default this is a fluent interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does @return
need to be @psalm-return
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use phpstan on this project, and it get promoted for Laravel projects.
I have updated the annotation to @return ($function is null ? AggregationBuilder : self)
, which is the documented way.
List of limitations: https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/#restrictions Since this operators are currently supported by the query builder, we need to keep building a |
438ccd7
to
0e82e24
Compare
@@ -49,6 +49,7 @@ | |||
use function uniqid; | |||
use function var_export; | |||
|
|||
/** @mixin Builder */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allows completions such as Model::where()->aggregate()->addField(
c46344f
to
3328e93
Compare
src/Eloquent/Builder.php
Outdated
{ | ||
$result = $this->toBase()->aggregate($function, $columns); | ||
|
||
return $result ?? $this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does @return
need to be @psalm-return
?
After review with @jmikola we decided to remove the feature of initializing the aggregation pipeline from the query builder with The
|
/** | ||
* Execute the aggregation pipeline and return the first result. | ||
*/ | ||
public function first(array $options = []): mixed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was concerned of potential conflict with a stage name, but $first
is an expression operator 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM in general, just a couple of minor suggestions.
src/Query/Builder.php
Outdated
throw new BadMethodCallException('Aggregation builder requires package mongodb/builder 0.2+'); | ||
} | ||
|
||
if ($columns !== [] && $columns !== ['*']) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason to allow []
for $columns
? IIRC, the previous signature changed the default value to an empty array, but you're preserving ['*']
now. Do you expect users to explicitly call aggregate(null, [])
? If not, I'd stick to just ['*']
here.
use FluentFactoryTrait; | ||
|
||
public function __construct( | ||
private MongoDBCollection|LaravelMongoDBCollection $collection, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason to allow MongoDB\Collection
here? It's only constructed as such in the test suite, but I presume you could just mock MongoDB\Laravel\Collection
instead there.
I do realize MongoDB\Laravel\Collection
just forwards method calls to the PHPLIB class, so there's no technical reason that a MongoDB\Collection
wouldn't work as well.
OK to leave as-is. I just wanted to bring this up since it makes the API more permissive and I don't expect users would be constructing this on their own anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect MongoDB\Laravel\Collection
to be deprecated soon, as it's used only for logging commands. We need to switch to driver monitoring features: PHPORM-56. This union type is forward-compatible.
src/Query/AggregationBuilder.php
Outdated
{ | ||
return (clone $this) | ||
->limit(1) | ||
->cursor($options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're going to apply limit(1)
I reckon it'd be more performant to just use get()
here.
/** | ||
* Execute the aggregation pipeline and return MongoDB cursor. | ||
*/ | ||
private function execute(array $options): CursorInterface&Iterator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though this is internal, I suppose you can't use MongoDB\Driver\Cursor
here since a CodecCursor might be returned?
Unrelated to this PR, but this made me wonder if we need to keep CursorInterface&Iterator
in place in PHPLIB 2.0, or if there were plans to integrate the Iterator API into CursorInterface. I asked @alcaeus about this in PHPLIB-1114.
Nothing for you here. I merely wanted to cross-reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow up on both open questions, but feel free to merge after doing so. Code changes LGTM.
Fix PHPORM-155
With this integration, it's possible to derivate any Query builder into an aggregation pipeline. The conditions built with the query builder are used as first stages (match, project, limit ...)
Requires mongodb/mongo-php-builder#67
Checklist