Skip to content
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

Add $search stage to aggregation pipeline builder #2516

Merged
merged 5 commits into from
Mar 29, 2023

Conversation

alcaeus
Copy link
Member

@alcaeus alcaeus commented Mar 28, 2023

Q A
Type feature
BC Break no
Fixed issues #2460

Summary

This adds the $search aggregation pipeline stage to the aggregation builder. This stage only works on MongoDB Atlas with Search indexes.

The following is missing from this PR:

  • The span operator - I'm currently looking into the documentation as it is using undocumented operators
  • The facet collector - this is relevant for the $searchMeta stage but would conflict with the facet stage that people could add down the line. For now, users should use the $$SEARCH_META aggregation variable
  • Documentation on how to create indexes (which is only possible through Atlas) and how to use the $search stage itself.

@alcaeus alcaeus self-assigned this Mar 28, 2023
@alcaeus
Copy link
Member Author

alcaeus commented Mar 28, 2023

Creating as a draft for initial review until #2515 is merged.

use Doctrine\ODM\MongoDB\Aggregation\Stage\Search\CompoundSearchOperatorInterface;
use Doctrine\ODM\MongoDB\Aggregation\Stage\Search\SupportsCompoundableOperatorsTrait;

class CompoundedAutocomplete extends Autocomplete implements CompoundSearchOperatorInterface
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these compounded operator classes could be created as anonymous classes, but that trips psalm into an endless recursion: vimeo/psalm#9573.

@alcaeus alcaeus marked this pull request as ready for review March 28, 2023 11:26
@alcaeus alcaeus requested a review from jmikola March 28, 2023 11:27
Copy link
Member

@jmikola jmikola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a first pass.

FYI: I had trouble following what all of the compound operator classes were used for. I understand the syntax in Atlas Search (although just barely), but this was too much to wrap my head around in a PR.

@alcaeus alcaeus added this to the 2.6.0 milestone Mar 28, 2023
@alcaeus
Copy link
Member Author

alcaeus commented Mar 28, 2023

I had trouble following what all of the compound operator classes were used for.

Yeah, that's where stuff gets messy. In a nutshell, the $search pipeline stage supports a single operator, for example:

{ $search: { query: 'jmikola', path: 'content' } }

This is constructed using:

$builder->search()
    ->text()
        ->query('jmikola')
        ->path('content')

However, when using compound, one can combine multiple operators in one of four conditions (must, mustNot, should, filter). For example:

$builder->search()
    ->compound()
        ->must()
            ->text()->query('jmikola')->path('content')
            ->equals()->value('alcaeus')->path('author')
        ->mustNot()
            ->text()->query('bad words')->path('content')

In this case, the result of text() has to return not only an instance of the Text class used to configure the operator, but at the same time an instance of the surrounding compound operator to allow for switching to another filter. We can do this by composing the original operator class with the interface for the compound operator and using a trait to fill in the functionality (as every operator added will have to be wrapped as well). I had originally planned returning an anonymous class instance for this, but Psalm did not agree with me there so I had to create those separate Compound... operator classes.

The idea behind all this is to not rely on some __call magic and instead provide proper typing information so tools like PhpStorm can show correct code completion options when using the fluent interface.

@alcaeus alcaeus requested a review from jmikola March 29, 2023 07:36
@alcaeus alcaeus merged commit 3091159 into doctrine:2.6.x Mar 29, 2023
@alcaeus alcaeus deleted the feature/search-agg-stage branch March 29, 2023 12:15
notrix pushed a commit to notrix/mongodb-odm that referenced this pull request Apr 6, 2023
* Add $search stage to aggregation pipeline builder

* Make AbstractSearchOperator::getExpression final

* Make appendScore method private for scored operators

* Add documentation links to search operator classes

* Separate wildcard and regex search operators
alcaeus added a commit that referenced this pull request Apr 11, 2023
* 2.6.x:
  Add $search stage to aggregation pipeline builder (#2516)
  Support new aggregation operators in builder (#2514)
  Drop support for PHP 7.4 (#2515)
  Support new aggregation pipeline stages in builder (#2513)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants